Skip to content

Commit

Permalink
Fixed bug with NamedTemporaryFile on Windows (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmichaeladavis authored May 31, 2020
1 parent 3e152c2 commit bed3f8a
Showing 1 changed file with 39 additions and 20 deletions.
59 changes: 39 additions & 20 deletions xtarfile/zstd.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from contextlib import contextmanager
from tarfile import open as tarfile_open
from tempfile import NamedTemporaryFile
from os import remove as os_remove

try:
import zstandard
Expand All @@ -14,29 +15,47 @@ def __init__(self, **kwargs):

@contextmanager
def read(self, path: str, mode: str):
with NamedTemporaryFile() as decompressed:
with open(path, 'rb') as compressed:
zstd = zstandard.ZstdDecompressor(**self.zstd_kwargs)
zstd.copy_stream(compressed, decompressed)
decompressed.seek(0)
archive = tarfile_open(mode=mode, fileobj=decompressed)
try:
yield archive
finally:
archive.close()
try:
with NamedTemporaryFile(delete=False) as decompressed:
with open(path, 'rb') as compressed:
zstd = zstandard.ZstdDecompressor(**self.zstd_kwargs)
zstd.copy_stream(compressed, decompressed)
decompressed.seek(0)
archive = tarfile_open(mode=mode, fileobj=decompressed)
try:
yield archive
finally:
archive.close()
finally:
# We delete it manually because otherwise on Windows
# it gets deleted before we move it to the output file location.
# This is because on Windows, file handles with the O_TEMPORARY
# flag (which is set if we pass `delete=True`) are deleted as
# soon as they're closed.
decompressed.close()
os_remove(decompressed.name)

@contextmanager
def write(self, path: str, mode: str):
with NamedTemporaryFile() as decompressed:
archive = tarfile_open(decompressed.name, mode=mode)
try:
yield archive
finally:
archive.close()
decompressed.seek(0)
with open(path, 'wb') as compressed:
zstd = zstandard.ZstdCompressor(**self.zstd_kwargs)
zstd.copy_stream(decompressed, compressed)
try:
with NamedTemporaryFile(delete=False) as decompressed:
archive = tarfile_open(decompressed.name, mode=mode)
try:
yield archive
finally:
archive.close()
decompressed.seek(0)
with open(path, 'wb') as compressed:
zstd = zstandard.ZstdCompressor(**self.zstd_kwargs)
zstd.copy_stream(decompressed, compressed)
finally:
# We delete it manually because otherwise on Windows
# it gets deleted before we move it to the output file location.
# This is because on Windows, file handles with the O_TEMPORARY
# flag (which is set if we pass `delete=True`) are deleted as
# soon as they're closed.
decompressed.close()
os_remove(decompressed.name)


if zstandard is None:
Expand Down

0 comments on commit bed3f8a

Please sign in to comment.