Skip to content

Commit 68ea4a0

Browse files
authored
Merge pull request #32 from pycompression/noclosestreams
gzip_ng_threaded.open no longer closes streams passed to it
2 parents 37011be + 6289b3a commit 68ea4a0

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Changelog
99
1010
version 0.5.0-dev
1111
-----------------
12+
+ Fix a bug where streams that were passed to gzip_ng_threaded.open where
13+
closed.
1214
+ Fix compatibility with Python 3.13
1315

1416
version 0.4.0

src/zlib_ng/gzip_ng_threaded.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,18 @@ def open(filename, mode="rb", compresslevel=gzip_ng._COMPRESS_LEVEL_TRADEOFF,
7878
def open_as_binary_stream(filename, open_mode):
7979
if isinstance(filename, (str, bytes)) or hasattr(filename, "__fspath__"):
8080
binary_file = builtins.open(filename, open_mode)
81+
closefd = True
8182
elif hasattr(filename, "read") or hasattr(filename, "write"):
8283
binary_file = filename
84+
closefd = False
8385
else:
8486
raise TypeError("filename must be a str or bytes object, or a file")
85-
return binary_file
87+
return binary_file, closefd
8688

8789

8890
class _ThreadedGzipReader(io.RawIOBase):
8991
def __init__(self, filename, queue_size=2, block_size=1024 * 1024):
90-
self.raw = open_as_binary_stream(filename, "rb")
92+
self.raw, self.closefd = open_as_binary_stream(filename, "rb")
9193
self.fileobj = zlib_ng._GzipReader(self.raw, buffersize=8 * block_size)
9294
self.pos = 0
9395
self.read_file = False
@@ -155,7 +157,8 @@ def close(self) -> None:
155157
self.running = False
156158
self.worker.join()
157159
self.fileobj.close()
158-
self.raw.close()
160+
if self.closefd:
161+
self.raw.close()
159162
self._closed = True
160163

161164
@property
@@ -246,7 +249,7 @@ def __init__(self,
246249
self._crc = 0
247250
self.running = False
248251
self._size = 0
249-
self.raw = open_as_binary_stream(filename, mode)
252+
self.raw, self.closefd = open_as_binary_stream(filename, mode)
250253
self._closed = False
251254
self._write_gzip_header()
252255
self.start()
@@ -334,7 +337,8 @@ def close(self) -> None:
334337
trailer = struct.pack("<II", self._crc, self._size & 0xFFFFFFFF)
335338
self.raw.write(trailer)
336339
self.raw.flush()
337-
self.raw.close()
340+
if self.closefd:
341+
self.raw.close()
338342
self._closed = True
339343

340344
@property

tests/test_gzip_ng_threaded.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,22 @@ def test_gzip_ng_threaded_append_text_mode(tmp_path):
190190
with gzip.open(test_file, "rt") as f:
191191
contents = f.read()
192192
assert contents == "ABCD"
193+
194+
195+
def test_threaded_reader_does_not_close_stream():
196+
test_stream = io.BytesIO()
197+
test_stream.write(gzip.compress(b"thisisatest"))
198+
test_stream.seek(0)
199+
with gzip_ng_threaded.open(test_stream, "rb") as f:
200+
text = f.read()
201+
assert not test_stream.closed
202+
assert text == b"thisisatest"
203+
204+
205+
def test_threaded_writer_does_not_close_stream():
206+
test_stream = io.BytesIO()
207+
with gzip_ng_threaded.open(test_stream, "wb") as f:
208+
f.write(b"thisisatest")
209+
assert not test_stream.closed
210+
test_stream.seek(0)
211+
assert gzip.decompress(test_stream.read()) == b"thisisatest"

0 commit comments

Comments
 (0)