Skip to content

Commit b02491f

Browse files
committed
Enable opening of files with long window sizes for zstd
1 parent e8dee1c commit b02491f

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

src/xopen/__init__.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -508,15 +508,26 @@ def _open_zst(
508508
assert compresslevel != 0
509509
if compresslevel is None:
510510
compresslevel = XOPEN_DEFAULT_ZST_COMPRESSION
511+
if zstandard:
512+
max_window_bits = zstandard.WINDOWLOG_MAX
513+
else:
514+
max_window_bits = 31
511515
if threads != 0:
512516
try:
513517
# zstd can compress using multiple cores
518+
program_args: Tuple[str, ...] = ("zstd",)
519+
if "r" in mode:
520+
# Only use --long=31 for decompression. Otherwise compression
521+
# will always use a very long window size, which will result
522+
# in very long compute times and the resulting archive not
523+
# openable by other tools without extra settings.
524+
program_args += (f"--long={max_window_bits}",)
514525
return _PipedCompressionProgram(
515526
filename,
516527
mode,
517528
compresslevel,
518529
threads,
519-
_PROGRAM_SETTINGS["zstd"],
530+
_ProgramSettings(program_args, tuple(range(1, 20)), "-T"),
520531
)
521532
except OSError:
522533
if zstandard is None:
@@ -525,11 +536,9 @@ def _open_zst(
525536

526537
if zstandard is None:
527538
raise ImportError("zstandard module (python-zstandard) not available")
528-
if compresslevel is not None and "r" not in mode:
529-
cctx = zstandard.ZstdCompressor(level=compresslevel)
530-
else:
531-
cctx = None
532-
f = zstandard.open(filename, mode, cctx=cctx) # type: ignore
539+
dctx = zstandard.ZstdDecompressor(max_window_size=2**max_window_bits)
540+
cctx = zstandard.ZstdCompressor(level=compresslevel)
541+
f = zstandard.open(filename, mode, cctx=cctx, dctx=dctx) # type: ignore
533542
if mode == "rb":
534543
return io.BufferedReader(f)
535544
return io.BufferedWriter(f) # mode "ab" and "wb"

0 commit comments

Comments
 (0)