Skip to content

Commit de9f047

Browse files
authored
add zst file handling for Python 3.14 and below (#428)
* add zst file handling for Python 3.14 and below * condition reordering
1 parent 970bee7 commit de9f047

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

biothings/utils/common.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,31 @@ def anyfile(infile, mode="r"):
173173
rawfile = os.path.splitext(infile)[0]
174174
filetype = os.path.splitext(infile)[1].lower()
175175

176+
# check if lower version zst handling is needed
177+
lower_version_zst = False
178+
if sys.version_info < (3, 14) and filetype == ".zst":
179+
import zstandard as zstd
180+
lower_version_zst = True
181+
182+
# tarfile handling. works for zst in Python >= 3.14
183+
if lower_version_zst or tarfile.is_tarfile(infile):
184+
if lower_version_zst:
185+
f = open(infile, "rb")
186+
dctx = zstd.ZstdDecompressor()
187+
reader = dctx.stream_reader(f)
188+
tar_file = tarfile.open(fileobj=reader, mode="r|") # streaming mode
189+
else:
190+
tar_file = tarfile.open(infile, mode)
176191

177-
# use tarfile built-in method to check for tar file before anything else
178-
if tarfile.is_tarfile(infile):
179-
tar_file = tarfile.open(infile, mode)
192+
extracted = None
180193
try:
181-
extracted = tar_file.extractfile(rawfile)
194+
if lower_version_zst:
195+
for member in tar_file:
196+
if member.name == rawfile:
197+
extracted = tar_file.extractfile(member)
198+
break
199+
else:
200+
extracted = tar_file.extractfile(rawfile)
182201
except KeyError:
183202
# provided rawfile does not appear in the tarball
184203
tar_file.close()
@@ -189,6 +208,9 @@ def anyfile(infile, mode="r"):
189208
tar_file.close()
190209
raise Exception("invalid target file: must be a regular file or a link")
191210

211+
if lower_version_zst:
212+
return extracted
213+
192214
return io.TextIOWrapper(extracted)
193215

194216
if filetype == ".gz":

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ dependencies = [
7171
"PyYAML>=5.1",
7272
'orjson>=3.10.16; python_version < "3.14.0"', # a faster json lib supports inf/nan and datetime, v3.10.16 is the first version requires Python 3.9+
7373
'orjson==3.11.4; python_version >= "3.14.0"', # orjson 3.11.5 cannot be built on Python 3.14t for now
74+
'zstandard>=0.21.0; python_version<"3.14"', # we need zst library before 3.14
7475
]
7576

7677
[project.optional-dependencies]

0 commit comments

Comments
 (0)