Make it easier to extend zipfile code
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 35.9k
- PR 合并指标
- PR 指标待抓取
描述
Feature or enhancement
Proposal:
This is follow up from https://github.com/python/cpython/issues/53416
Even if stdlib will never support WinZIP AES encrpyption, it would be useful to allow for downstream project to implement it.
There is pyzipper based on a fork but the code is now very different to what we have in stdlib.
it would help if the stdlib zipfile code is written to allow dependency injection
A very simple proof of concept downstream code is here that can only read AES ZIP files is here
https://github.com/chevah/zipfile-aes
It is using a patch for stdblib that looks like this
--- lib/python3.12/zipfile/__init__.py 2025-07-17 11:19:59.376677338 +0100
+++ src/dev_tools/zipfile_init.py 2025-07-17 11:21:50.797894299 +0100
@@ -1286,6 +1286,9 @@
"""
+ _ZipInfo = ZipInfo
+ _ZipExtFile = ZipExtFile
+
fp = None # Set here since __del__ checks it
_windows_illegal_name_trans_table = None
@@ -1456,7 +1459,7 @@
# Historical ZIP filename encoding
filename = filename.decode(self.metadata_encoding or 'cp437')
# Create ZipInfo instance to store file information
- x = ZipInfo(filename)
+ x = self._ZipInfo(filename)
x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH])
x.comment = fp.read(centdir[_CD_COMMENT_LENGTH])
x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET]
@@ -1592,11 +1595,11 @@
"Attempt to use ZIP archive that was already closed")
# Make sure we have an info object
- if isinstance(name, ZipInfo):
+ if isinstance(name, self._ZipInfo):
# 'name' is already an info object
zinfo = name
elif mode == 'w':
- zinfo = ZipInfo(name)
+ zinfo = self._ZipInfo(name)
zinfo.compress_type = self.compression
zinfo._compresslevel = self.compresslevel
else:
@@ -1664,7 +1667,7 @@
else:
pwd = None
- return ZipExtFile(zef_file, mode, zinfo, pwd, True)
+ return self._ZipExtFile(zef_file, mode, zinfo, pwd, True)
except:
zef_file.close()
raise
@@ -1762,7 +1765,7 @@
"""Extract the ZipInfo object 'member' to a physical
file on the path targetpath.
"""
- if not isinstance(member, ZipInfo):
+ if not isinstance(member, self._ZipInfo):
member = self.getinfo(member)
# build the destination pathname, replacing
@@ -1838,7 +1841,7 @@
"Can't write to ZIP archive while an open writing handle exists"
)
- zinfo = ZipInfo.from_file(filename, arcname,
+ zinfo = self._ZipInfo.from_file(filename, arcname,
strict_timestamps=self._strict_timestamps)
if zinfo.is_dir():
@@ -1868,8 +1871,8 @@
the name of the file in the archive."""
if isinstance(data, str):
data = data.encode("utf-8")
- if not isinstance(zinfo_or_arcname, ZipInfo):
- zinfo = ZipInfo(filename=zinfo_or_arcname,
+ if not isinstance(zinfo_or_arcname, self._ZipInfo):
+ zinfo = self._ZipInfo(filename=zinfo_or_arcname,
date_time=time.localtime(time.time())[:6])
zinfo.compress_type = self.compression
zinfo._compresslevel = self.compresslevel
@@ -1910,7 +1913,7 @@
directory_name = zinfo_or_directory_name
if not directory_name.endswith("/"):
directory_name += "/"
- zinfo = ZipInfo(directory_name)
+ zinfo = self._ZipInfo(directory_name)
zinfo.compress_size = 0
zinfo.CRC = 0
zinfo.external_attr = ((0o40000 | mode) & 0xFFFF) << 16
Would you consider such a patch ?
Thanks
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
https://github.com/python/cpython/issues/53416
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 lib/python3.12/zipfile/init.py 开始,重点查看 ZipFile、ZipInfo 和 ZipExtFile,然后审阅 issue 53416 和 81719 以及 PR 14957,了解之前的设计讨论。当下游项目无需维护 fork 即可扩展 zipfile 实现以支持 AES 等功能,并且已根据相关行为验证所接受的扩展机制时,即视为完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- tooling
- Issue 类型
- 功能
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 需要澄清
- 新手友好度
- 30/100