PEP 608 – 协调的 Python 版本发布
- 作者:
- Miro Hrončok <miro at hroncok.cz>, Victor Stinner <vstinner at python.org>
- 状态:
- 已拒绝
- 类型:
- 标准跟踪
- 创建时间:
- 2019-10-25
- Python 版本:
- 3.9
摘要
在选定项目的兼容版本可用之前,阻止 Python 版本发布。
如果 Python 版本发布经理认为该项目很快就会被修复,或者问题严重程度足够低,他们可以决定发布 Python,即使该项目不兼容。
基本原理
PEP 将选定项目的维护者纳入 Python 版本发布周期。它带来了很多好处
- 在 Python 最终版本发布之前检测更多错误
- 在 Python 最终版本发布之前讨论并可能撤销不兼容更改
- 在发布新的 Python 最终版本时,增加兼容项目的数量
参与 Python 测试阶段的项目太少
目前,Python 测试版在最终 3.x.0 版本发布前四个月可用。
在测试阶段报告的错误可以轻松修复,如果错误足够严重,可以阻止发布。
不兼容更改在测试阶段进行讨论:增强文档,解释如何更新代码,或考虑撤销这些更改。
即使越来越多的项目在其 CI 中的 Python 主分支上进行测试,但前 50 个 PyPI 项目中仍然有太多项目只与新 Python 版本兼容几个星期,甚至几个月,才在 Python 最终版本发布后兼容。
DeprecationWarning 被忽略
Python 有一个明确的流程来弃用功能。在删除某个功能之前,必须在至少一个 Python 版本中发出 DeprecationWarning。
在实践中,DeprecationWarning 警告在主要的 Python 项目中被忽略了好几年。通常,维护者解释说警告太多,因此他们 simply ignore warnings。此外,DeprecationWarning 默认情况下是静默的(除了在 __main__
模块中:PEP 565)。
即使越来越多的项目使用警告作为错误进行测试 (-Werror
),Python 核心开发人员仍然不知道在删除某个功能时有多少项目会被破坏。
需要协调
当在 Python 最终版本发布后发现和讨论问题和不兼容更改时,修复 Python 会变得更加复杂和昂贵。一旦某个 API 成为官方最终版本的一部分,Python 应该在整个 3.x 版本的生命周期内提供向后兼容性。一些操作系统可能会与有 bug 的最终版本一起发布,并且可能需要几个月的时间才能更新。
太多项目只在 Python 最终版本发布后才更新到新 Python 版本,这使得新 Python 版本在发布时几乎无法用于运行大型应用程序。
建议在所有选定项目的兼容版本可用之前,阻止 Python 版本发布。
更短的 Python 版本发布周期
PEP 602: Python 年度发布周期 和 PEP 605: CPython 的滚动功能发布流 希望更频繁地发布 Python,以便更快地发布新功能。
问题是,每个 Python 3.x
版本都会破坏很多项目。
协调的 Python 版本发布减少了被破坏项目的数量,使新的 Python 版本发布更易于使用。
规范
默认情况下,在所有选定项目的兼容版本可用之前,Python 版本发布会被阻止。
在发布最终 Python 版本之前,Python 版本发布经理有责任发送一份关于每个选定项目的兼容性状态的报告。建议在每次测试版发布时发送这样的报告,以了解发展趋势并尽早发现问题。
如果 Python 版本发布经理认为该项目很快就会被修复,或者问题严重程度足够低,他们可以决定发布 Python,即使该项目不兼容。
在每次 Python 版本发布后,可以更新项目列表,删除旧项目并添加新项目。例如,删除旧的未使用依赖项并添加新的依赖项。如果整个流程没有过长时间地阻止 Python 版本发布,则该列表可以增长。
限制延迟
当向项目报告了与下一个 Python 版本有关的构建或测试问题时,维护者有一个月的时间回复。如果没有回复,该项目可以从阻止 Python 版本发布的项目列表中排除。
许多项目已经在 CI 中的 Python 主分支上进行测试。可以在 Python 版本发布的早期阶段发现问题,这应该提供足够的时间来处理它们。可以为尚未在下一个 Python 版本上进行测试的项目添加更多 CI。
一旦了解了选定项目的问题,Python 版本发布经理和相关项目维护者可以根据具体情况进行讨论。并非所有问题都需要阻止 Python 版本发布。
选定项目
阻止 Python 版本发布的项目列表(共 27 个)
- 项目 (13)
- aiohttp
- cryptography
- Cython
- Django
- numpy
- pandas
- pip
- requests
- scipy
- Sphinx(构建 Python 所需)
- sqlalchemy
- pytest
- tox
- 直接和间接依赖项 (14)
- certifi(urllib3 所需)
- cffi(cryptography 所需)
- chardet(Sphinx 所需)
- colorama(pip 所需)
- docutils(Sphinx 所需)
- idna(Sphinx 和 requests 所需)
- jinja2(Sphinx 所需)
- MarkupSafe(Sphinx 所需)
- psycopg2(Django 所需)
- pycparser(cffi 所需)
- setuptools(pip 和大量的 Python 项目所需)
- six(大量的 Python 项目所需)
- urllib3(requests 所需)
- wheel(pip 所需)
项目选择方式
构建 Python 所用的项目应该包含在列表中,例如 Sphinx。
最受欢迎的项目是从下载次数最多的 PyPI 项目中挑选的。
列表中还包含了大多数项目的依赖项,因为单个不兼容的依赖项可能会阻止整个项目。一些依赖项被排除在外,以减少列表长度。
测试依赖项,如 pytest 和 tox,也应该包含在内。如果一个项目无法测试,就不能发布新版本。
该列表应该足够长,以便很好地了解将项目移植到下一个 Python 的成本,但要足够短,不要过长时间地阻止 Python 版本发布。
显然,鼓励不在列表中的项目也报告与下一个 Python 版本相关的问题,并在下一个 Python 版本上运行 CI。
不兼容更改
这里的定义很广泛:任何导致在构建或测试项目时出现问题的 Python 更改。
有关不兼容更改的更多示例,请参阅 PEP 606: Python 兼容版本。
示例
存在不同类型的不兼容更改
- Python 构建中的更改。例如,Python 3.8 从
sys.abiflags
中删除了'm'
(代表 pymalloc),这会影响像 Linux 发行版这样的 Python 供应商。 - C 扩展构建中的更改。例如,Python 3.8 不再将 C 扩展链接到 libpython,而 Python 3.7 删除了
os.errno
到errno
模块的别名。 - 删除函数。例如,在 Python 3.9 中删除了 collections 到 ABC 类别的别名。
- 更改函数签名
- 拒绝以前接受的类型(例如:只接受
int
,拒绝float
)。 - 添加新的必需参数。
- 将位置或关键字参数转换为仅位置参数。
- 拒绝以前接受的类型(例如:只接受
- 行为更改。例如,Python 3.8 现在按插入顺序序列化 XML 属性,而不是按名称排序它们。
- 新的警告。由于越来越多的项目使用所有警告作为错误进行测试,因此任何新的警告都可能导致项目测试失败。
- 从 C API 中删除的函数。
- 在 C API 中使结构变得不透明。例如,在 Python 3.8 中,PyInterpreterState 变得不透明,这会破坏访问
interp->modules
的项目(应该使用PyImport_GetModuleDict()
代替)。
清理 Python 和 DeprecationWarning
Python 之禅 (PEP 20) 的格言之一是
应该有一种,最好只有一种显而易见的方式来做这件事。
当 Python 发展时,新的方法不可避免地会出现。DeprecationWarning
被用来建议使用新的方法,但许多开发人员忽略了这些默认情况下是静默的警告。
有时,同时支持两种方法的维护成本很低,但 Python 核心开发人员更倾向于放弃旧方法,以便清理 Python 代码库和标准库。这种类型的更改是向后不兼容的。
随着 Python 2 支持的结束,可能会出现比以往更多的不兼容更改,这是一个清理旧 Python 代码的好机会。
分布式 CI
可以使用分布式 CI 自动检查选定项目是否与 Python 主分支兼容。
可以重复使用现有的 CI。
可以为尚未在下一个 Python 版本上进行测试的项目添加新的 CI。
建议在下一个 Python 版本上进行测试时,将 DeprecationWarning 警告视为错误。
在下一个 Python 版本上测试项目的作业不一定是“强制性”的(阻止整个 CI)。在 Python 版本发布的测试阶段出现失败是可以的。该作业只需要在最终 Python 版本发布时通过即可。
版权
本文件放置在公有领域或 CC0-1.0-Universal 许可下,以更宽松的许可为准。
来源:https://github.com/python/peps/blob/main/peps/pep-0608.rst