@@ -719,6 +719,42 @@ class ZstdTestsWithSourceFile(AbstractTestsWithSourceFile,
719719 unittest .TestCase ):
720720 compression = zipfile .ZIP_ZSTANDARD
721721
722+ def test_read_multiframe (self ):
723+ first = b'first frame' * 400
724+ second = b'second frame' * 400
725+ data = first + second
726+
727+ class MultiframeCompressor :
728+ def compress (self , value ):
729+ value = bytes (value )
730+ return (zipfile .zstd .compress (value [:len (first )]) +
731+ zipfile .zstd .compress (value [len (first ):]))
732+
733+ def flush (self ):
734+ return b''
735+
736+ archive = io .BytesIO ()
737+ with mock .patch .object (zipfile , '_get_compressor' ,
738+ return_value = MultiframeCompressor ()):
739+ with zipfile .ZipFile (archive , 'w' , self .compression ) as zipfp :
740+ zipfp .writestr ('multiframe' , data )
741+
742+ with zipfile .ZipFile (archive ) as zipfp :
743+ self .assertEqual (zipfp .read ('multiframe' ), data )
744+
745+ with zipfile .ZipFile (archive ) as zipfp :
746+ with zipfp .open ('multiframe' ) as fp :
747+ chunk = fp ._read1 (1 )
748+ self .assertLessEqual (len (chunk ), fp .MIN_READ_SIZE )
749+ self .assertEqual (chunk + fp .read (), data )
750+
751+ # Exercise a frame boundary between two reads from the archive.
752+ with zipfile .ZipFile (archive ) as zipfp :
753+ with zipfp .open ('multiframe' ) as fp :
754+ fp .MIN_READ_SIZE = 1
755+ self .assertEqual (b'' .join (iter (lambda : fp .read (1 ), b'' )),
756+ data )
757+
722758class AbstractTestZip64InSmallFiles :
723759 # These tests test the ZIP64 functionality without using large files,
724760 # see test_zipfile64 for proper tests.
0 commit comments