@@ -1836,22 +1836,31 @@ def test_repack_file_entry_before_first_file(self):
18361836 with zipfile .ZipFile (TESTFN ) as zh :
18371837 self .assertIsNone (zh .testzip ())
18381838
1839- def test_repack_bytes_between_files (self ):
1840- """Should remove bytes between local file entries."""
1839+ def test_repack_bytes_before_removed_files (self ):
1840+ """Should preserve if there are bytes before stale local file entries."""
18411841 for ii in ([1 ], [1 , 2 ], [2 ]):
18421842 with self .subTest (remove = ii ):
18431843 # calculate the expected results
1844- test_files = [data for j , data in enumerate (self .test_files ) if j not in ii ]
1845- expected_zinfos = self ._prepare_zip_from_test_files (TESTFN , test_files )
1844+ with open (TESTFN , 'wb' ) as fh :
1845+ with zipfile .ZipFile (fh , 'w' , self .compression ) as zh :
1846+ for i , (file , data ) in enumerate (self .test_files ):
1847+ if i == ii [0 ]:
1848+ fh .write (b' dummy bytes ' )
1849+ zh .start_dir = fh .tell ()
1850+ zh .writestr (file , data )
1851+ for i in ii :
1852+ zh .remove (self .test_files [i ][0 ])
1853+ expected_zinfos = [ComparableZipInfo (zi ) for zi in zh .infolist ()]
18461854 expected_size = os .path .getsize (TESTFN )
18471855
18481856 # do the removal and check the result
18491857 with open (TESTFN , 'wb' ) as fh :
18501858 with zipfile .ZipFile (fh , 'w' , self .compression ) as zh :
18511859 for i , (file , data ) in enumerate (self .test_files ):
1860+ if i == ii [0 ]:
1861+ fh .write (b' dummy bytes ' )
1862+ zh .start_dir = fh .tell ()
18521863 zh .writestr (file , data )
1853- fh .write (b' dummy bytes ' )
1854- zh .start_dir = fh .tell ()
18551864 with zipfile .ZipFile (TESTFN , 'a' , self .compression ) as zh :
18561865 for i in ii :
18571866 zh .remove (self .test_files [i ][0 ])
@@ -1870,6 +1879,87 @@ def test_repack_bytes_between_files(self):
18701879 with zipfile .ZipFile (TESTFN ) as zh :
18711880 self .assertIsNone (zh .testzip ())
18721881
1882+ def test_repack_bytes_after_removed_files (self ):
1883+ """Should keep extra bytes if there are bytes after stale local file entries."""
1884+ for ii in ([1 ], [1 , 2 ], [2 ]):
1885+ with self .subTest (remove = ii ):
1886+ # calculate the expected results
1887+ with open (TESTFN , 'wb' ) as fh :
1888+ with zipfile .ZipFile (fh , 'w' , self .compression ) as zh :
1889+ for i , (file , data ) in enumerate (self .test_files ):
1890+ if i not in ii :
1891+ zh .writestr (file , data )
1892+ if i == ii [- 1 ]:
1893+ fh .write (b' dummy bytes ' )
1894+ zh .start_dir = fh .tell ()
1895+ expected_zinfos = [ComparableZipInfo (zi ) for zi in zh .infolist ()]
1896+ expected_size = os .path .getsize (TESTFN )
1897+
1898+ # do the removal and check the result
1899+ with open (TESTFN , 'wb' ) as fh :
1900+ with zipfile .ZipFile (fh , 'w' , self .compression ) as zh :
1901+ for i , (file , data ) in enumerate (self .test_files ):
1902+ zh .writestr (file , data )
1903+ if i == ii [- 1 ]:
1904+ fh .write (b' dummy bytes ' )
1905+ zh .start_dir = fh .tell ()
1906+ with zipfile .ZipFile (TESTFN , 'a' , self .compression ) as zh :
1907+ for i in ii :
1908+ zh .remove (self .test_files [i ][0 ])
1909+ zh .repack ()
1910+
1911+ # check infolist
1912+ self .assertEqual (
1913+ [ComparableZipInfo (zi ) for zi in zh .infolist ()],
1914+ expected_zinfos ,
1915+ )
1916+
1917+ # check file size
1918+ self .assertEqual (os .path .getsize (TESTFN ), expected_size )
1919+
1920+ # make sure the zip file is still valid
1921+ with zipfile .ZipFile (TESTFN ) as zh :
1922+ self .assertIsNone (zh .testzip ())
1923+
1924+ def test_repack_bytes_between_removed_files (self ):
1925+ """Should strip only local file entries before random bytes."""
1926+ # calculate the expected results
1927+ with open (TESTFN , 'wb' ) as fh :
1928+ with zipfile .ZipFile (fh , 'w' , self .compression ) as zh :
1929+ zh .writestr (* self .test_files [0 ])
1930+ fh .write (b' dummy bytes ' )
1931+ zh .start_dir = fh .tell ()
1932+ zh .writestr (* self .test_files [2 ])
1933+ zh .remove (self .test_files [2 ][0 ])
1934+ expected_zinfos = [ComparableZipInfo (zi ) for zi in zh .infolist ()]
1935+ expected_size = os .path .getsize (TESTFN )
1936+
1937+ # do the removal and check the result
1938+ with open (TESTFN , 'wb' ) as fh :
1939+ with zipfile .ZipFile (fh , 'w' , self .compression ) as zh :
1940+ zh .writestr (* self .test_files [0 ])
1941+ zh .writestr (* self .test_files [1 ])
1942+ fh .write (b' dummy bytes ' )
1943+ zh .start_dir = fh .tell ()
1944+ zh .writestr (* self .test_files [2 ])
1945+ with zipfile .ZipFile (TESTFN , 'a' , self .compression ) as zh :
1946+ zh .remove (self .test_files [1 ][0 ])
1947+ zh .remove (self .test_files [2 ][0 ])
1948+ zh .repack ()
1949+
1950+ # check infolist
1951+ self .assertEqual (
1952+ [ComparableZipInfo (zi ) for zi in zh .infolist ()],
1953+ expected_zinfos ,
1954+ )
1955+
1956+ # check file size
1957+ self .assertEqual (os .path .getsize (TESTFN ), expected_size )
1958+
1959+ # make sure the zip file is still valid
1960+ with zipfile .ZipFile (TESTFN ) as zh :
1961+ self .assertIsNone (zh .testzip ())
1962+
18731963 def test_repack_zip64 (self ):
18741964 """Should correctly handle file entries with zip64."""
18751965 for ii in ([0 ], [0 , 1 ], [1 ], [2 ]):
@@ -2011,7 +2101,7 @@ def test_repack_data_descriptor_no_sig_strict(self):
20112101 if self .compression not in (zipfile .ZIP_STORED , zipfile .ZIP_LZMA ):
20122102 self .skipTest ('require unsupported decompression method' )
20132103
2014- for ii in ([0 ], [0 , 1 ]):
2104+ for ii in ([0 ], [0 , 1 ], [ 1 ], [ 2 ] ):
20152105 with self .subTest (remove = ii ):
20162106 # calculate the expected results
20172107 with open (TESTFN , 'wb' ) as fh :
@@ -2055,7 +2145,7 @@ def test_repack_data_descriptor_no_sig_strict_by_decompressoin(self):
20552145 if self .compression in (zipfile .ZIP_STORED , zipfile .ZIP_LZMA ):
20562146 self .skipTest ('require supported decompression method' )
20572147
2058- for ii in ([0 ], [0 , 1 ]):
2148+ for ii in ([0 ], [0 , 1 ], [ 1 ], [ 2 ] ):
20592149 with self .subTest (remove = ii ):
20602150 # calculate the expected results
20612151 test_files = [data for j , data in enumerate (self .test_files ) if j not in ii ]
0 commit comments