@@ -508,15 +508,26 @@ def _open_zst(
508
508
assert compresslevel != 0
509
509
if compresslevel is None :
510
510
compresslevel = XOPEN_DEFAULT_ZST_COMPRESSION
511
+ if zstandard :
512
+ max_window_bits = zstandard .WINDOWLOG_MAX
513
+ else :
514
+ max_window_bits = 31
511
515
if threads != 0 :
512
516
try :
513
517
# 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 } " ,)
514
525
return _PipedCompressionProgram (
515
526
filename ,
516
527
mode ,
517
528
compresslevel ,
518
529
threads ,
519
- _PROGRAM_SETTINGS [ "zstd" ] ,
530
+ _ProgramSettings ( program_args , tuple ( range ( 1 , 20 )), "-T" ) ,
520
531
)
521
532
except OSError :
522
533
if zstandard is None :
@@ -525,11 +536,9 @@ def _open_zst(
525
536
526
537
if zstandard is None :
527
538
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
533
542
if mode == "rb" :
534
543
return io .BufferedReader (f )
535
544
return io .BufferedWriter (f ) # mode "ab" and "wb"
0 commit comments