@@ -1372,7 +1372,7 @@ class ZipFile:
13721372 """ Class with methods to open, read, write, close, list zip files.
13731373
13741374 z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=True,
1375- compresslevel=None)
1375+ compresslevel=None, _ZipInfo=ZipInfo, _ZipExtFile=ZipExtFile )
13761376
13771377 file: Either the path to the file, or a file-like object.
13781378 If it is a path, the file will be opened and closed by ZipFile.
@@ -1392,21 +1392,32 @@ class ZipFile:
13921392 When using ZIP_ZSTANDARD integers -7 though 22 are common,
13931393 see the CompressionParameter enum in compression.zstd for
13941394 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.
13961405 """
13971406
13981407 fp = None # Set here since __del__ checks it
13991408 _windows_illegal_name_trans_table = None
14001409
14011410 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 ):
14031413 """Open the ZIP file with mode read 'r', write 'w', exclusive create 'x',
14041414 or append 'a'."""
14051415 if mode not in ('r' , 'w' , 'x' , 'a' ):
14061416 raise ValueError ("ZipFile requires mode 'r', 'w', 'x', or 'a'" )
14071417
14081418 _check_compression (compression )
1409-
1419+ self ._ZipInfo = _ZipInfo
1420+ self ._ZipExtFile = _ZipExtFile
14101421 self ._allowZip64 = allowZip64
14111422 self ._didModify = False
14121423 self .debug = 0 # Level of printing: 0 through 3
@@ -1558,7 +1569,7 @@ def _RealGetContents(self):
15581569 # Historical ZIP filename encoding
15591570 filename = filename .decode (self .metadata_encoding or 'cp437' )
15601571 # Create ZipInfo instance to store file information
1561- x = ZipInfo (filename )
1572+ x = self . _ZipInfo (filename )
15621573 x .extra = fp .read (centdir [_CD_EXTRA_FIELD_LENGTH ])
15631574 x .comment = fp .read (centdir [_CD_COMMENT_LENGTH ])
15641575 x .header_offset = centdir [_CD_LOCAL_HEADER_OFFSET ]
@@ -1693,11 +1704,11 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
16931704 "Attempt to use ZIP archive that was already closed" )
16941705
16951706 # Make sure we have an info object
1696- if isinstance (name , ZipInfo ):
1707+ if isinstance (name , self . _ZipInfo ):
16971708 # 'name' is already an info object
16981709 zinfo = name
16991710 elif mode == 'w' :
1700- zinfo = ZipInfo (name )
1711+ zinfo = self . _ZipInfo (name )
17011712 zinfo .compress_type = self .compression
17021713 zinfo .compress_level = self .compresslevel
17031714 else :
@@ -1774,7 +1785,7 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
17741785 else :
17751786 pwd = None
17761787
1777- return ZipExtFile (zef_file , mode + 'b' , zinfo , pwd , True )
1788+ return self . _ZipExtFile (zef_file , mode + 'b' , zinfo , pwd , True )
17781789 except :
17791790 zef_file .close ()
17801791 raise
@@ -1872,7 +1883,7 @@ def _extract_member(self, member, targetpath, pwd):
18721883 """Extract the ZipInfo object 'member' to a physical
18731884 file on the path targetpath.
18741885 """
1875- if not isinstance (member , ZipInfo ):
1886+ if not isinstance (member , self . _ZipInfo ):
18761887 member = self .getinfo (member )
18771888
18781889 # build the destination pathname, replacing
@@ -1952,7 +1963,7 @@ def write(self, filename, arcname=None,
19521963 "Can't write to ZIP archive while an open writing handle exists"
19531964 )
19541965
1955- zinfo = ZipInfo .from_file (filename , arcname ,
1966+ zinfo = self . _ZipInfo .from_file (filename , arcname ,
19561967 strict_timestamps = self ._strict_timestamps )
19571968
19581969 if zinfo .is_dir ():
@@ -1982,10 +1993,10 @@ def writestr(self, zinfo_or_arcname, data,
19821993 the name of the file in the archive."""
19831994 if isinstance (data , str ):
19841995 data = data .encode ("utf-8" )
1985- if isinstance (zinfo_or_arcname , ZipInfo ):
1996+ if isinstance (zinfo_or_arcname , self . _ZipInfo ):
19861997 zinfo = zinfo_or_arcname
19871998 else :
1988- zinfo = ZipInfo (zinfo_or_arcname )._for_archive (self )
1999+ zinfo = self . _ZipInfo (zinfo_or_arcname )._for_archive (self )
19892000
19902001 if not self .fp :
19912002 raise ValueError (
@@ -2008,15 +2019,15 @@ def writestr(self, zinfo_or_arcname, data,
20082019
20092020 def mkdir (self , zinfo_or_directory_name , mode = 511 ):
20102021 """Creates a directory inside the zip archive."""
2011- if isinstance (zinfo_or_directory_name , ZipInfo ):
2022+ if isinstance (zinfo_or_directory_name , self . _ZipInfo ):
20122023 zinfo = zinfo_or_directory_name
20132024 if not zinfo .is_dir ():
20142025 raise ValueError ("The given ZipInfo does not describe a directory" )
20152026 elif isinstance (zinfo_or_directory_name , str ):
20162027 directory_name = zinfo_or_directory_name
20172028 if not directory_name .endswith ("/" ):
20182029 directory_name += "/"
2019- zinfo = ZipInfo (directory_name )
2030+ zinfo = self . _ZipInfo (directory_name )
20202031 zinfo .compress_size = 0
20212032 zinfo .CRC = 0
20222033 zinfo .external_attr = ((0o40000 | mode ) & 0xFFFF ) << 16
0 commit comments