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 Beta 阶段的项目太少
目前,Python Beta 版本在 3.x.0 正式发布前四个月可用。
Beta 阶段报告的错误可以轻松修复,如果足够严重,可能会阻止发布。
在 Python 正式发布前,Beta 阶段会讨论不兼容的更改:增强文档以解释如何更新代码,或考虑回滚这些更改。
尽管越来越多的项目在 Python 的 master 分支上进行 CI 测试,但 PyPI 项目 Top 50 中仍有太多项目在 Python 正式发布后几周甚至几个月才与新的 Python 版本兼容。
DeprecationWarning 被忽略
Python 有明确的功能弃用流程。在删除某个功能之前,必须至少在一次 Python 发布中发出 DeprecationWarning。
实际上,在主要的 Python 项目中,DeprecationWarning 被忽略了多年。通常,维护者解释说警告太多,所以他们干脆忽略了警告。此外,DeprecationWarning 默认是静默的(除了在 `__main__` 模块中: PEP 565)。
尽管越来越多的项目在将警告视为错误(`-Werror`)的情况下运行其测试套件,但 Python 核心开发人员仍然不知道在删除某个功能时有多少项目会因此中断。
需要协调
当在 Python 正式发布后发现和讨论问题及不兼容的更改时,修复 Python 会变得更加复杂和昂贵。一旦 API 成为官方正式发布的一部分,Python 应该在整个 3.x 版本生命周期内提供向后兼容性。一些操作系统可能随附有错误的正式版本,并且可能需要几个月才能更新。
太多的项目在 Python 正式发布后才更新到新的 Python 版本,这使得在 Python 发布时,新的 Python 版本几乎无法用于运行大型应用程序。
提议在可用所有选定项目的兼容版本之前,阻止 Python 发布。
更短的 Python 发布周期
PEP 602:Python 年度发布周期 和 PEP 605:CPython 的滚动功能发布流 希望更频繁地发布 Python 以更快地交付新功能。
问题是,每个 Python `3.x` 发布都会破坏许多项目。
协调 Python 发布可以减少中断项目的数量,并使新的 Python 发布更易于使用。
规范
默认情况下,在可用所有选定项目的兼容版本之前,Python 发布将被阻止。
在发布最终 Python 版本之前,Python 发布管理器负责发送一份关于选定项目每个项目兼容性状态的报告。建议在每次 Beta 版本发布时发送此类报告,以查看进展并尽早发现问题。
如果 Python 发布管理器认为某个项目很快就会修复,或者问题的严重性足够低,则可以决定发布 Python,即使该项目不兼容。
在每次 Python 发布之后,可以更新项目列表以删除旧项目并添加新项目。例如,删除旧的未使用依赖项并添加新的。如果整个过程不会过长时间地阻止 Python 发布,列表可能会增长。
限制延迟
当下一个 Python 版本出现构建或测试问题并报告给某个项目时,维护者有一个月的时间来回复。如果没有回复,该项目可能会从阻止 Python 发布的项目中排除。
许多项目已经在 Python 的 master 分支上使用 CI 进行测试。问题可以在 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 中不透明的结构。例如,`PyInterpreterState` 在 Python 3.8 中变得不透明,这破坏了访问 `interp->modules` 的项目(应该使用 `PyImport_GetModuleDict()`)。
清理 Python 和 DeprecationWarning
《Python 之禅》(PEP 20)的座右铭之一是:
应该有,并且最好只有一种——显而易见的方法可以做到这一点。
当 Python 发展时,新的方法不可避免地会出现。`DeprecationWarning` 会被发出以建议使用新方法,但许多开发人员忽略了这些默认是静默的警告。
有时,支持两种方法维护成本很小,但 Python 核心开发人员倾向于删除旧方法以清理 Python 代码库和标准库。这种类型的更改是向后不兼容的。
随着 Python 2 支持的结束,应该预期不兼容的更改比以往任何时候都多,这是清理旧 Python 代码的好机会。
分布式 CI
可以使用分布式 CI 自动检查选定项目是否与 Python 的 master 分支兼容。
可以重用现有的 CI。
可以为尚未在下一个 Python 版本上进行测试的项目添加新的 CI。
建议在下一个 Python 版本上进行测试时,将 DeprecationWarning 视为错误。
在下一个 Python 版本上测试某个项目的作业不必是“强制性”的(阻止整个 CI)。在 Python 发布 Beta 阶段出现失败是可以接受的。作业只需在 Python 正式发布时通过即可。
版权
本文档置于公共领域或 CC0-1.0-Universal 许可证下,以更宽松者为准。
来源:https://github.com/python/peps/blob/main/peps/pep-0608.rst
最后修改日期:2025-02-01 08:55:40 GMT