@@ -802,7 +802,7 @@ def unused_data(self):
802802 return b''
803803
804804 @property
805- def _needs_input (self ):
805+ def needs_input (self ):
806806 # While the LZMA properties header is still being buffered, more input
807807 # is required; afterwards defer to the wrapped decompressor so a bounded
808808 # decompress() call can be drained across reads.
@@ -893,25 +893,6 @@ def _get_compressor(compress_type, compresslevel=None):
893893 return None
894894
895895
896- def _decompressor_needs_input (decompressor , default ):
897- # bz2/zstd expose the stdlib decompressor's public needs_input; the LZMA
898- # wrapper keeps it private (_needs_input) to avoid adding public API.
899- # A decompressor with neither attribute reports *default*.
900- needs_input = getattr (decompressor , "needs_input" , None )
901- if needs_input is None :
902- needs_input = getattr (decompressor , "_needs_input" , default )
903- return needs_input
904-
905-
906- def _decompressor_bounds_output (decompressor ):
907- # The stdlib bzip2/LZMA/Zstandard decompressors report needs_input and
908- # accept decompress(data, max_length). A third-party decompressor
909- # installed by replacing _get_decompressor() may support neither; it is
910- # then read unbounded, as before the bounded-decompression fix.
911- return (hasattr (decompressor , "needs_input" )
912- or hasattr (decompressor , "_needs_input" ))
913-
914-
915896def _get_decompressor (compress_type ):
916897 _check_compression (compress_type )
917898 if compress_type == ZIP_STORED :
@@ -1019,7 +1000,7 @@ def __init__(self, fileobj, mode, zipinfo, pwd=None,
10191000 self ._compress_left = zipinfo .compress_size
10201001 self ._left = zipinfo .file_size
10211002
1022- self ._set_decompressor ( )
1003+ self ._decompressor = _get_decompressor ( self . _compress_type )
10231004
10241005 self ._eof = False
10251006 self ._readbuffer = b''
@@ -1202,11 +1183,6 @@ def read1(self, n):
12021183 break
12031184 return buf
12041185
1205- def _set_decompressor (self ):
1206- self ._decompressor = _get_decompressor (self ._compress_type )
1207- self ._decompress_bounded = _decompressor_bounds_output (
1208- self ._decompressor )
1209-
12101186 def _read1 (self , n ):
12111187 # Read up to n compressed bytes with at most one read() system call,
12121188 # decrypt and decompress them.
@@ -1224,7 +1200,7 @@ def _read1(self, n):
12241200 else :
12251201 # bzip2/lzma/zstd: a bounded decompress() call may leave input
12261202 # buffered inside the decompressor; drain that before reading more.
1227- if _decompressor_needs_input (self ._decompressor , default = True ):
1203+ if getattr (self ._decompressor , "needs_input" , True ):
12281204 data = self ._read2 (n )
12291205 else :
12301206 data = b''
@@ -1239,18 +1215,27 @@ def _read1(self, n):
12391215 not self ._decompressor .unconsumed_tail )
12401216 if self ._eof :
12411217 data += self ._decompressor .flush ()
1242- elif self . _decompress_bounded :
1218+ else :
12431219 # Bound the output of a single decompress() call (mirroring the
12441220 # DEFLATE path above) so that a small compressed member cannot
12451221 # expand into one unbounded read.
1246- data = self ._decompressor .decompress (data , max (n , self .MIN_READ_SIZE ))
1222+ try :
1223+ data = self ._decompressor .decompress (data , max (n , self .MIN_READ_SIZE ))
1224+ except TypeError :
1225+ # See MonkeypatchedDecompressorTests in test_core.py
1226+ warnings ._deprecated (
1227+ 'one-argument decompress()' ,
1228+ 'The decompress() method of '
1229+ + type (self ._decompressor ).__name__
1230+ + ' should take two arguments, data and max_length.'
1231+ + ' One-argument calls will stop working before'
1232+ + ' Python 3.21.' ,
1233+ remove = (3 , 21 ),
1234+ stacklevel = 4 )
1235+ data = self ._decompressor .decompress (data )
12471236 self ._eof = (self ._decompressor .eof or
12481237 self ._compress_left <= 0 and
1249- _decompressor_needs_input (self ._decompressor ,
1250- default = True ))
1251- else :
1252- data = self ._decompressor .decompress (data )
1253- self ._eof = self ._decompressor .eof or self ._compress_left <= 0
1238+ getattr (self ._decompressor , "needs_input" , True ))
12541239
12551240 data = data [:self ._left ]
12561241 self ._left -= len (data )
@@ -1339,7 +1324,7 @@ def seek(self, offset, whence=os.SEEK_SET):
13391324 self ._left = self ._orig_file_size
13401325 self ._readbuffer = b''
13411326 self ._offset = 0
1342- self ._set_decompressor ( )
1327+ self ._decompressor = _get_decompressor ( self . _compress_type )
13431328 self ._eof = False
13441329 read_offset = new_pos
13451330 if self ._decrypter is not None :
0 commit comments