Skip to content

Commit 4b2176e

Browse files
committed
1 parent 11c0937 commit 4b2176e

File tree

3 files changed

+54
-56
lines changed

3 files changed

+54
-56
lines changed

Doc/library/zipfile.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ ZipFile Objects
527527
a path is provided.
528528

529529
This does not physically remove the local file entry from the archive.
530-
Call :meth:`ZipFile.repack` afterwards to reclaim space.
530+
Call :meth:`repack` afterwards to reclaim space.
531531

532532
The archive must be opened with mode ``'w'``, ``'x'`` or ``'a'``.
533533

Lib/test/test_zipfile/test_core.py

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,8 +1362,11 @@ class ZstdWriterTests(AbstractWriterTests, unittest.TestCase):
13621362
compression = zipfile.ZIP_ZSTANDARD
13631363

13641364

1365-
def ComparableZipInfo(zinfo):
1366-
return (zinfo.filename, zinfo.header_offset, zinfo.compress_size, zinfo.CRC)
1365+
class ComparableZipInfo:
1366+
keys = [i for i in zipfile.ZipInfo.__slots__ if not i.startswith('_')]
1367+
1368+
def __new__(cls, zinfo):
1369+
return {i: getattr(zinfo, i) for i in cls.keys}
13671370

13681371
_struct_pack = struct.pack
13691372

@@ -1379,6 +1382,8 @@ def struct_pack_no_dd_sig(fmt, *values):
13791382

13801383
class RepackHelperMixin:
13811384
"""Common helpers for remove and repack."""
1385+
maxDiff = 8192
1386+
13821387
@classmethod
13831388
def _prepare_test_files(cls):
13841389
return [
@@ -1389,14 +1394,11 @@ def _prepare_test_files(cls):
13891394

13901395
@classmethod
13911396
def _prepare_zip_from_test_files(cls, zfname, test_files, force_zip64=False):
1392-
zinfos = []
13931397
with zipfile.ZipFile(zfname, 'w', cls.compression) as zh:
13941398
for file, data in test_files:
13951399
with zh.open(file, 'w', force_zip64=force_zip64) as fh:
13961400
fh.write(data)
1397-
zinfo = zh.getinfo(file)
1398-
zinfos.append(ComparableZipInfo(zinfo))
1399-
return zinfos
1401+
return list(zh.infolist())
14001402

14011403
class AbstractRemoveTests(RepackHelperMixin):
14021404
@classmethod
@@ -1416,7 +1418,7 @@ def test_remove_by_name(self):
14161418
# check infolist
14171419
self.assertEqual(
14181420
[ComparableZipInfo(zi) for zi in zh.infolist()],
1419-
[zi for j, zi in enumerate(zinfos) if j != i],
1421+
[ComparableZipInfo(zi) for j, zi in enumerate(zinfos) if j != i],
14201422
)
14211423

14221424
# check NameToInfo cache
@@ -1437,7 +1439,7 @@ def test_remove_by_zinfo(self):
14371439
# check infolist
14381440
self.assertEqual(
14391441
[ComparableZipInfo(zi) for zi in zh.infolist()],
1440-
[zi for j, zi in enumerate(zinfos) if j != i],
1442+
[ComparableZipInfo(zi) for j, zi in enumerate(zinfos) if j != i],
14411443
)
14421444

14431445
# check NameToInfo cache
@@ -1478,13 +1480,13 @@ def test_remove_by_name_duplicated(self):
14781480
# check infolist
14791481
self.assertEqual(
14801482
[ComparableZipInfo(zi) for zi in zh.infolist()],
1481-
[zinfos[0], zinfos[2]],
1483+
[ComparableZipInfo(zi) for zi in [zinfos[0], zinfos[2]]],
14821484
)
14831485

14841486
# check NameToInfo cache
14851487
self.assertEqual(
14861488
ComparableZipInfo(zh.getinfo('file.txt')),
1487-
zinfos[0],
1489+
ComparableZipInfo(zinfos[0]),
14881490
)
14891491

14901492
# make sure the zip file is still valid
@@ -1499,7 +1501,7 @@ def test_remove_by_name_duplicated(self):
14991501
# check infolist
15001502
self.assertEqual(
15011503
[ComparableZipInfo(zi) for zi in zh.infolist()],
1502-
[zinfos[2]],
1504+
[ComparableZipInfo(zi) for zi in [zinfos[2]]],
15031505
)
15041506

15051507
# check NameToInfo cache
@@ -1528,13 +1530,13 @@ def test_remove_by_zinfo_duplicated(self):
15281530
# check infolist
15291531
self.assertEqual(
15301532
[ComparableZipInfo(zi) for zi in zh.infolist()],
1531-
[zinfos[1], zinfos[2]],
1533+
[ComparableZipInfo(zi) for zi in [zinfos[1], zinfos[2]]],
15321534
)
15331535

15341536
# check NameToInfo cache
15351537
self.assertEqual(
15361538
ComparableZipInfo(zh.getinfo('file.txt')),
1537-
zinfos[1],
1539+
ComparableZipInfo(zinfos[1]),
15381540
)
15391541

15401542
# make sure the zip file is still valid
@@ -1548,13 +1550,13 @@ def test_remove_by_zinfo_duplicated(self):
15481550
# check infolist
15491551
self.assertEqual(
15501552
[ComparableZipInfo(zi) for zi in zh.infolist()],
1551-
[zinfos[0], zinfos[2]],
1553+
[ComparableZipInfo(zi) for zi in [zinfos[0], zinfos[2]]],
15521554
)
15531555

15541556
# check NameToInfo cache
15551557
self.assertEqual(
15561558
ComparableZipInfo(zh.getinfo('file.txt')),
1557-
zinfos[0],
1559+
ComparableZipInfo(zinfos[0]),
15581560
)
15591561

15601562
# make sure the zip file is still valid
@@ -1570,7 +1572,7 @@ def test_remove_by_zinfo_duplicated(self):
15701572
# check infolist
15711573
self.assertEqual(
15721574
[ComparableZipInfo(zi) for zi in zh.infolist()],
1573-
[zinfos[2]],
1575+
[ComparableZipInfo(zi) for zi in [zinfos[2]]],
15741576
)
15751577

15761578
# check NameToInfo cache
@@ -1591,7 +1593,7 @@ def test_remove_zip64(self):
15911593
# check infolist
15921594
self.assertEqual(
15931595
[ComparableZipInfo(zi) for zi in zh.infolist()],
1594-
[zi for j, zi in enumerate(zinfos) if j != i],
1596+
[ComparableZipInfo(zi) for j, zi in enumerate(zinfos) if j != i],
15951597
)
15961598

15971599
# check NameToInfo cache
@@ -1626,14 +1628,14 @@ def test_remove_mode_w(self):
16261628
with zipfile.ZipFile(TESTFN, 'w') as zh:
16271629
for file, data in self.test_files:
16281630
zh.writestr(file, data)
1629-
zinfos = [ComparableZipInfo(zi) for zi in zh.infolist()]
1631+
zinfos = list(zh.infolist())
16301632

16311633
zh.remove(self.test_files[0][0])
16321634

16331635
# check infolist
16341636
self.assertEqual(
16351637
[ComparableZipInfo(zi) for zi in zh.infolist()],
1636-
[zinfos[1], zinfos[2]],
1638+
[ComparableZipInfo(zi) for zi in [zinfos[1], zinfos[2]]],
16371639
)
16381640

16391641
# check NameToInfo cache
@@ -1648,14 +1650,14 @@ def test_remove_mode_x(self):
16481650
with zipfile.ZipFile(TESTFN, 'x') as zh:
16491651
for file, data in self.test_files:
16501652
zh.writestr(file, data)
1651-
zinfos = [ComparableZipInfo(zi) for zi in zh.infolist()]
1653+
zinfos = list(zh.infolist())
16521654

16531655
zh.remove(self.test_files[0][0])
16541656

16551657
# check infolist
16561658
self.assertEqual(
16571659
[ComparableZipInfo(zi) for zi in zh.infolist()],
1658-
[zinfos[1], zinfos[2]],
1660+
[ComparableZipInfo(zi) for zi in [zinfos[1], zinfos[2]]],
16591661
)
16601662

16611663
# check NameToInfo cache
@@ -1714,7 +1716,7 @@ def test_repack_basic(self):
17141716
# check infolist
17151717
self.assertEqual(
17161718
[ComparableZipInfo(zi) for zi in zh.infolist()],
1717-
expected_zinfos,
1719+
[ComparableZipInfo(zi) for zi in expected_zinfos],
17181720
)
17191721

17201722
# check file size
@@ -1766,7 +1768,7 @@ def test_repack_bytes_before_first_file(self):
17661768
# check infolist
17671769
self.assertEqual(
17681770
[ComparableZipInfo(zi) for zi in zh.infolist()],
1769-
expected_zinfos,
1771+
[ComparableZipInfo(zi) for zi in expected_zinfos],
17701772
)
17711773

17721774
# check file size
@@ -1800,7 +1802,7 @@ def test_repack_magic_before_first_file(self):
18001802
# check infolist
18011803
self.assertEqual(
18021804
[ComparableZipInfo(zi) for zi in zh.infolist()],
1803-
expected_zinfos,
1805+
[ComparableZipInfo(zi) for zi in expected_zinfos],
18041806
)
18051807

18061808
# check file size
@@ -1846,7 +1848,7 @@ def test_repack_file_entry_before_first_file(self):
18461848
# check infolist
18471849
self.assertEqual(
18481850
[ComparableZipInfo(zi) for zi in zh.infolist()],
1849-
expected_zinfos,
1851+
[ComparableZipInfo(zi) for zi in expected_zinfos],
18501852
)
18511853

18521854
# check file size
@@ -1856,6 +1858,7 @@ def test_repack_file_entry_before_first_file(self):
18561858
with zipfile.ZipFile(TESTFN) as zh:
18571859
self.assertIsNone(zh.testzip())
18581860

1861+
@mock.patch.object(time, 'time', new=lambda: 315504000) # fix time for ZipFile.writestr()
18591862
def test_repack_bytes_before_removed_files(self):
18601863
"""Should preserve if there are bytes before stale local file entries."""
18611864
for ii in ([1], [1, 2], [2]):
@@ -1870,7 +1873,7 @@ def test_repack_bytes_before_removed_files(self):
18701873
zh.writestr(file, data)
18711874
for i in ii:
18721875
zh.remove(self.test_files[i][0])
1873-
expected_zinfos = [ComparableZipInfo(zi) for zi in zh.infolist()]
1876+
expected_zinfos = list(zh.infolist())
18741877
expected_size = os.path.getsize(TESTFN)
18751878

18761879
# do the removal and check the result
@@ -1889,7 +1892,7 @@ def test_repack_bytes_before_removed_files(self):
18891892
# check infolist
18901893
self.assertEqual(
18911894
[ComparableZipInfo(zi) for zi in zh.infolist()],
1892-
expected_zinfos,
1895+
[ComparableZipInfo(zi) for zi in expected_zinfos],
18931896
)
18941897

18951898
# check file size
@@ -1899,6 +1902,7 @@ def test_repack_bytes_before_removed_files(self):
18991902
with zipfile.ZipFile(TESTFN) as zh:
19001903
self.assertIsNone(zh.testzip())
19011904

1905+
@mock.patch.object(time, 'time', new=lambda: 315504000) # fix time for ZipFile.writestr()
19021906
def test_repack_bytes_after_removed_files(self):
19031907
"""Should keep extra bytes if there are bytes after stale local file entries."""
19041908
for ii in ([1], [1, 2], [2]):
@@ -1912,7 +1916,7 @@ def test_repack_bytes_after_removed_files(self):
19121916
if i == ii[-1]:
19131917
fh.write(b' dummy bytes ')
19141918
zh.start_dir = fh.tell()
1915-
expected_zinfos = [ComparableZipInfo(zi) for zi in zh.infolist()]
1919+
expected_zinfos = list(zh.infolist())
19161920
expected_size = os.path.getsize(TESTFN)
19171921

19181922
# do the removal and check the result
@@ -1931,7 +1935,7 @@ def test_repack_bytes_after_removed_files(self):
19311935
# check infolist
19321936
self.assertEqual(
19331937
[ComparableZipInfo(zi) for zi in zh.infolist()],
1934-
expected_zinfos,
1938+
[ComparableZipInfo(zi) for zi in expected_zinfos],
19351939
)
19361940

19371941
# check file size
@@ -1941,6 +1945,7 @@ def test_repack_bytes_after_removed_files(self):
19411945
with zipfile.ZipFile(TESTFN) as zh:
19421946
self.assertIsNone(zh.testzip())
19431947

1948+
@mock.patch.object(time, 'time', new=lambda: 315504000) # fix time for ZipFile.writestr()
19441949
def test_repack_bytes_between_removed_files(self):
19451950
"""Should strip only local file entries before random bytes."""
19461951
# calculate the expected results
@@ -1951,7 +1956,7 @@ def test_repack_bytes_between_removed_files(self):
19511956
zh.start_dir = fh.tell()
19521957
zh.writestr(*self.test_files[2])
19531958
zh.remove(self.test_files[2][0])
1954-
expected_zinfos = [ComparableZipInfo(zi) for zi in zh.infolist()]
1959+
expected_zinfos = list(zh.infolist())
19551960
expected_size = os.path.getsize(TESTFN)
19561961

19571962
# do the removal and check the result
@@ -1970,7 +1975,7 @@ def test_repack_bytes_between_removed_files(self):
19701975
# check infolist
19711976
self.assertEqual(
19721977
[ComparableZipInfo(zi) for zi in zh.infolist()],
1973-
expected_zinfos,
1978+
[ComparableZipInfo(zi) for zi in expected_zinfos],
19741979
)
19751980

19761981
# check file size
@@ -1992,7 +1997,7 @@ def test_repack_prepended_bytes(self):
19921997
fh.write(b'dummy ')
19931998
fh.write(fz.read())
19941999
with zipfile.ZipFile(TESTFN) as zh:
1995-
expected_zinfos = [ComparableZipInfo(zi) for zi in zh.infolist()]
2000+
expected_zinfos = list(zh.infolist())
19962001
expected_size = os.path.getsize(TESTFN)
19972002

19982003
# do the removal and check the result
@@ -2010,7 +2015,7 @@ def test_repack_prepended_bytes(self):
20102015
# check infolist
20112016
self.assertEqual(
20122017
[ComparableZipInfo(zi) for zi in zh.infolist()],
2013-
expected_zinfos,
2018+
[ComparableZipInfo(zi) for zi in expected_zinfos],
20142019
)
20152020

20162021
# check file size
@@ -2055,7 +2060,7 @@ def test_repack_removed_basic(self):
20552060
# check infolist
20562061
self.assertEqual(
20572062
[ComparableZipInfo(zi) for zi in zh.infolist()],
2058-
expected_zinfos,
2063+
[ComparableZipInfo(zi) for zi in expected_zinfos],
20592064
)
20602065

20612066
# check file size
@@ -2098,20 +2103,20 @@ def test_repack_removed_partial(self):
20982103
with zipfile.ZipFile(TESTFN) as zh:
20992104
self.assertIsNone(zh.testzip())
21002105

2106+
@mock.patch.object(time, 'time', new=lambda: 315504000) # fix time for ZipFile.writestr()
21012107
def test_repack_removed_bytes_between_files(self):
21022108
"""Should not remove bytes between local file entries."""
21032109
for ii in ([0], [1], [2]):
21042110
with self.subTest(removed=ii):
21052111
# calculate the expected results
2106-
expected_zinfos = []
21072112
with open(TESTFN, 'wb') as fh:
21082113
with zipfile.ZipFile(fh, 'w', self.compression) as zh:
21092114
for j, (file, data) in enumerate(self.test_files):
21102115
if j not in ii:
21112116
zh.writestr(file, data)
2112-
expected_zinfos.append(ComparableZipInfo(zh.getinfo(file)))
21132117
fh.write(b' dummy bytes ')
21142118
zh.start_dir = fh.tell()
2119+
expected_zinfos = list(zh.infolist())
21152120
expected_size = os.path.getsize(TESTFN)
21162121

21172122
# do the removal and check the result
@@ -2128,7 +2133,7 @@ def test_repack_removed_bytes_between_files(self):
21282133
# check infolist
21292134
self.assertEqual(
21302135
[ComparableZipInfo(zi) for zi in zh.infolist()],
2131-
expected_zinfos,
2136+
[ComparableZipInfo(zi) for zi in expected_zinfos],
21322137
)
21332138

21342139
# check file size
@@ -2184,7 +2189,7 @@ def test_repack_removed_prepended_bytes(self):
21842189
fh.write(b'dummy ')
21852190
fh.write(fz.read())
21862191
with zipfile.ZipFile(TESTFN) as zh:
2187-
expected_zinfos = [ComparableZipInfo(zi) for zi in zh.infolist()]
2192+
expected_zinfos = list(zh.infolist())
21882193
expected_size = os.path.getsize(TESTFN)
21892194

21902195
# do the removal and check the result
@@ -2201,7 +2206,7 @@ def test_repack_removed_prepended_bytes(self):
22012206
# check infolist
22022207
self.assertEqual(
22032208
[ComparableZipInfo(zi) for zi in zh.infolist()],
2204-
expected_zinfos,
2209+
[ComparableZipInfo(zi) for zi in expected_zinfos],
22052210
)
22062211

22072212
# check file size

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy