Skip to content

Commit

Permalink
Fix on windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
plietar committed Apr 19, 2024
1 parent c0c6cd0 commit 090aee4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 13 deletions.
17 changes: 6 additions & 11 deletions src/outpack/filestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
import os.path
import shutil
import stat
import tempfile
from contextlib import contextmanager
from pathlib import Path

from outpack.hash import Hash, hash_parse, hash_validate_file
from outpack.util import openable_temporary_file


class FileStore:
Expand Down Expand Up @@ -85,16 +85,11 @@ def onerror(func, path, _exc_info):

@contextmanager
def tmp(self):
# On a newer version of tempfile we could use `delete_on_close = False`
# see
# https://github.com/mrc-ide/outpack-py/pull/33#discussion_r1500522877
path = self._path / "tmp"
path.mkdir(exist_ok=True)
f = tempfile.NamedTemporaryFile(dir=path, delete=False)
try:

with openable_temporary_file(dir=path) as f:
# Close the file (but don't delete it). We are only interested in
# using the path.
f.close()
yield f.name
finally:
try:
os.unlink(f.name)
except OSError:
pass
22 changes: 22 additions & 0 deletions src/outpack/util.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import datetime
import os
import runpy
import tempfile
import time
from contextlib import contextmanager
from itertools import filterfalse, tee
from pathlib import Path
from typing import Optional


def find_file_descend(filename, path):
Expand Down Expand Up @@ -141,3 +143,23 @@ def partition(pred, iterable):
# partition(is_odd, range(10)) --> 1 3 5 7 9 and 0 2 4 6 8
t1, t2 = tee(iterable)
return list(filter(pred, t1)), list(filterfalse(pred, t2))


@contextmanager
def openable_temporary_file(*, mode: str = "w+b", dir: Optional[str] = None):
# On Windows, a NamedTemporaryFile with `delete=True` cannot be reopened,
# which makes its name pretty useless. On Python 3.12, a new
# delete_on_close flag is solves this issue, but we can't depend on that
# yet. This block mimicks that feature.
#
# https://bugs.python.org/issue14243
# https://github.com/mrc-ide/outpack-py/pull/33#discussion_r1500522877
f = tempfile.NamedTemporaryFile(mode=mode, dir=dir, delete=False)
try:
yield f
finally:
f.close()
try:
os.unlink(f.name)
except OSError:
pass
4 changes: 2 additions & 2 deletions tests/helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import random
import shutil
import string
import tempfile
import textwrap
from contextlib import contextmanager
from pathlib import Path
Expand All @@ -16,6 +15,7 @@
from outpack.packet import Packet
from outpack.root import root_open
from outpack.schema import outpack_schema_version
from outpack.util import openable_temporary_file


@contextmanager
Expand Down Expand Up @@ -173,7 +173,7 @@ def run_snippet(name, code, root, **kwargs):
# We work around that by returning the value out-of-band, in a temporary
# file outside of the report's directory. That way it is completely
# transparent to the caller
with tempfile.NamedTemporaryFile() as output:
with openable_temporary_file() as output:
wrapped = f"""
def body():
{textwrap.indent(code, " ")}
Expand Down

0 comments on commit 090aee4

Please sign in to comment.