Skip to content

Commit dd4fbc8

Browse files
committed
Add private members via init to make it easier to subclass.
1 parent 9b451fb commit dd4fbc8

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

Lib/zipfile/__init__.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
zipfile.ZipFile.__init__ was updated to make it easier to subclass and
2+
extend it to support new encryption methods.

0 commit comments

Comments
 (0)