@@ -1372,7 +1372,7 @@ class ZipFile:
1372
1372
""" Class with methods to open, read, write, close, list zip files.
1373
1373
1374
1374
z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=True,
1375
- compresslevel=None)
1375
+ compresslevel=None, _ZipInfo=ZipInfo, _ZipExtFile=ZipExtFile )
1376
1376
1377
1377
file: Either the path to the file, or a file-like object.
1378
1378
If it is a path, the file will be opened and closed by ZipFile.
@@ -1392,21 +1392,32 @@ class ZipFile:
1392
1392
When using ZIP_ZSTANDARD integers -7 though 22 are common,
1393
1393
see the CompressionParameter enum in compression.zstd for
1394
1394
details.
1395
-
1395
+ _ZipInfo: A class that can replace ZipInfo. This is designed to help extend
1396
+ ZipFile, for example to implement other encryption or compression
1397
+ methods.
1398
+ This is private as there is no commitemnt to maintain backward
1399
+ compatibitly.
1400
+ _ZipExtFile: A class that can replace ZipExtFile. This is designed to help
1401
+ extend ZipFile, for example to implement other encryption
1402
+ or compression methods.
1403
+ This is private as there is no commitemnt to maintain backward
1404
+ compatibitly.
1396
1405
"""
1397
1406
1398
1407
fp = None # Set here since __del__ checks it
1399
1408
_windows_illegal_name_trans_table = None
1400
1409
1401
1410
def __init__ (self , file , mode = "r" , compression = ZIP_STORED , allowZip64 = True ,
1402
- compresslevel = None , * , strict_timestamps = True , metadata_encoding = None ):
1411
+ compresslevel = None , * , strict_timestamps = True , metadata_encoding = None ,
1412
+ _ZipInfo = ZipInfo , _ZipExtFile = ZipExtFile ):
1403
1413
"""Open the ZIP file with mode read 'r', write 'w', exclusive create 'x',
1404
1414
or append 'a'."""
1405
1415
if mode not in ('r' , 'w' , 'x' , 'a' ):
1406
1416
raise ValueError ("ZipFile requires mode 'r', 'w', 'x', or 'a'" )
1407
1417
1408
1418
_check_compression (compression )
1409
-
1419
+ self ._ZipInfo = _ZipInfo
1420
+ self ._ZipExtFile = _ZipExtFile
1410
1421
self ._allowZip64 = allowZip64
1411
1422
self ._didModify = False
1412
1423
self .debug = 0 # Level of printing: 0 through 3
@@ -1558,7 +1569,7 @@ def _RealGetContents(self):
1558
1569
# Historical ZIP filename encoding
1559
1570
filename = filename .decode (self .metadata_encoding or 'cp437' )
1560
1571
# Create ZipInfo instance to store file information
1561
- x = ZipInfo (filename )
1572
+ x = self . _ZipInfo (filename )
1562
1573
x .extra = fp .read (centdir [_CD_EXTRA_FIELD_LENGTH ])
1563
1574
x .comment = fp .read (centdir [_CD_COMMENT_LENGTH ])
1564
1575
x .header_offset = centdir [_CD_LOCAL_HEADER_OFFSET ]
@@ -1693,11 +1704,11 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
1693
1704
"Attempt to use ZIP archive that was already closed" )
1694
1705
1695
1706
# Make sure we have an info object
1696
- if isinstance (name , ZipInfo ):
1707
+ if isinstance (name , self . _ZipInfo ):
1697
1708
# 'name' is already an info object
1698
1709
zinfo = name
1699
1710
elif mode == 'w' :
1700
- zinfo = ZipInfo (name )
1711
+ zinfo = self . _ZipInfo (name )
1701
1712
zinfo .compress_type = self .compression
1702
1713
zinfo .compress_level = self .compresslevel
1703
1714
else :
@@ -1774,7 +1785,7 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
1774
1785
else :
1775
1786
pwd = None
1776
1787
1777
- return ZipExtFile (zef_file , mode + 'b' , zinfo , pwd , True )
1788
+ return self . _ZipExtFile (zef_file , mode + 'b' , zinfo , pwd , True )
1778
1789
except :
1779
1790
zef_file .close ()
1780
1791
raise
@@ -1872,7 +1883,7 @@ def _extract_member(self, member, targetpath, pwd):
1872
1883
"""Extract the ZipInfo object 'member' to a physical
1873
1884
file on the path targetpath.
1874
1885
"""
1875
- if not isinstance (member , ZipInfo ):
1886
+ if not isinstance (member , self . _ZipInfo ):
1876
1887
member = self .getinfo (member )
1877
1888
1878
1889
# build the destination pathname, replacing
@@ -1952,7 +1963,7 @@ def write(self, filename, arcname=None,
1952
1963
"Can't write to ZIP archive while an open writing handle exists"
1953
1964
)
1954
1965
1955
- zinfo = ZipInfo .from_file (filename , arcname ,
1966
+ zinfo = self . _ZipInfo .from_file (filename , arcname ,
1956
1967
strict_timestamps = self ._strict_timestamps )
1957
1968
1958
1969
if zinfo .is_dir ():
@@ -1982,10 +1993,10 @@ def writestr(self, zinfo_or_arcname, data,
1982
1993
the name of the file in the archive."""
1983
1994
if isinstance (data , str ):
1984
1995
data = data .encode ("utf-8" )
1985
- if isinstance (zinfo_or_arcname , ZipInfo ):
1996
+ if isinstance (zinfo_or_arcname , self . _ZipInfo ):
1986
1997
zinfo = zinfo_or_arcname
1987
1998
else :
1988
- zinfo = ZipInfo (zinfo_or_arcname )._for_archive (self )
1999
+ zinfo = self . _ZipInfo (zinfo_or_arcname )._for_archive (self )
1989
2000
1990
2001
if not self .fp :
1991
2002
raise ValueError (
@@ -2008,15 +2019,15 @@ def writestr(self, zinfo_or_arcname, data,
2008
2019
2009
2020
def mkdir (self , zinfo_or_directory_name , mode = 511 ):
2010
2021
"""Creates a directory inside the zip archive."""
2011
- if isinstance (zinfo_or_directory_name , ZipInfo ):
2022
+ if isinstance (zinfo_or_directory_name , self . _ZipInfo ):
2012
2023
zinfo = zinfo_or_directory_name
2013
2024
if not zinfo .is_dir ():
2014
2025
raise ValueError ("The given ZipInfo does not describe a directory" )
2015
2026
elif isinstance (zinfo_or_directory_name , str ):
2016
2027
directory_name = zinfo_or_directory_name
2017
2028
if not directory_name .endswith ("/" ):
2018
2029
directory_name += "/"
2019
- zinfo = ZipInfo (directory_name )
2030
+ zinfo = self . _ZipInfo (directory_name )
2020
2031
zinfo .compress_size = 0
2021
2032
zinfo .CRC = 0
2022
2033
zinfo .external_attr = ((0o40000 | mode ) & 0xFFFF ) << 16
0 commit comments