Skip to content

Commit 54ebf53

Browse files
committed
Prevent unclosed filehandles by moving opening logic after other tests
1 parent c84f90d commit 54ebf53

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

src/isal/igzip_threaded.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,13 @@ def open(filename, mode="rb", compresslevel=igzip._COMPRESS_LEVEL_TRADEOFF,
5757
except: # noqa: E722
5858
threads = 1
5959
open_mode = mode.replace("t", "b")
60-
if isinstance(filename, (str, bytes)) or hasattr(filename, "__fspath__"):
61-
binary_file = builtins.open(filename, open_mode)
62-
elif hasattr(filename, "read") or hasattr(filename, "write"):
63-
binary_file = filename
64-
else:
65-
raise TypeError("filename must be a str or bytes object, or a file")
6660
if "r" in mode:
6761
gzip_file = io.BufferedReader(
68-
_ThreadedGzipReader(binary_file, block_size=block_size))
62+
_ThreadedGzipReader(filename, block_size=block_size))
6963
else:
7064
gzip_file = io.BufferedWriter(
7165
_ThreadedGzipWriter(
72-
fp=binary_file,
66+
filename,
7367
block_size=block_size,
7468
level=compresslevel,
7569
threads=threads
@@ -81,10 +75,20 @@ def open(filename, mode="rb", compresslevel=igzip._COMPRESS_LEVEL_TRADEOFF,
8175
return gzip_file
8276

8377

78+
def open_as_binary_stream(filename, open_mode):
79+
if isinstance(filename, (str, bytes)) or hasattr(filename, "__fspath__"):
80+
binary_file = builtins.open(filename, open_mode)
81+
elif hasattr(filename, "read") or hasattr(filename, "write"):
82+
binary_file = filename
83+
else:
84+
raise TypeError("filename must be a str or bytes object, or a file")
85+
return binary_file
86+
87+
8488
class _ThreadedGzipReader(io.RawIOBase):
85-
def __init__(self, fp, queue_size=2, block_size=1024 * 1024):
86-
self.raw = fp
87-
self.fileobj = igzip._IGzipReader(fp, buffersize=8 * block_size)
89+
def __init__(self, filename, queue_size=2, block_size=1024 * 1024):
90+
self.raw = open_as_binary_stream(filename, "rb")
91+
self.fileobj = igzip._IGzipReader(self.raw, buffersize=8 * block_size)
8892
self.pos = 0
8993
self.read_file = False
9094
self.queue = queue.Queue(queue_size)
@@ -193,15 +197,14 @@ class _ThreadedGzipWriter(io.RawIOBase):
193197
compressing and output is handled in one thread.
194198
"""
195199
def __init__(self,
196-
fp: BinaryIO,
200+
filename,
197201
level: int = isal_zlib.ISAL_DEFAULT_COMPRESSION,
198202
threads: int = 1,
199203
queue_size: int = 1,
200204
block_size: int = 1024 * 1024,
201205
):
202206
self.lock = threading.Lock()
203207
self.exception: Optional[Exception] = None
204-
self.raw = fp
205208
self.level = level
206209
self.previous_block = b""
207210
# Deflating random data results in an output a little larger than the
@@ -236,6 +239,7 @@ def __init__(self,
236239
self.running = False
237240
self._size = 0
238241
self._closed = False
242+
self.raw = open_as_binary_stream(filename, "wb")
239243
self._write_gzip_header()
240244
self.start()
241245

tests/test_igzip_threaded.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def test_threaded_write_oversized_block_no_error(threads):
9999
@pytest.mark.parametrize("threads", [1, 3])
100100
def test_threaded_write_error(threads):
101101
f = igzip_threaded._ThreadedGzipWriter(
102-
fp=io.BytesIO(), level=3,
102+
io.BytesIO(), level=3,
103103
threads=threads, block_size=8 * 1024)
104104
# Bypass the write method which should not allow blocks larger than
105105
# block_size.

0 commit comments

Comments
 (0)