Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 605 – CPython 的滚动功能发布流

作者:
Steve Dower <steve.dower at python.org>, Alyssa Coghlan <ncoghlan at gmail.com>
讨论至:
Discourse 帖子
状态:
已拒绝
类型:
信息性
创建日期:
2019-09-20
Python 版本:
3.9
发布历史:
2019-10-01, 2019-10-06, 2019-10-20

目录

拒绝通知

此 PEP 已被否决,取而代之的是 PEP 602。潜在的 alpha/beta 交替被认为过于令人困惑,而两年一次的发布周期被认为太长。

摘要

长期以来,CPython 的名义功能发布周期一直是“每 18-24 个月”,近年来,一直稳定在“18 个月”的窗口期内。PEP 607 提供了一些关于该周期选择所带来的问题的背景信息,以及在提出变更建议时需要考虑的风险。

本 PEP 中的提案旨在允许 CPython 的用户群自行选择加入两个不同的但重叠的群体:

  • 使用每 24 个月发布一次的稳定功能版本(及其相关的维护版本流)的用户;以及
  • 早期采用替代 CPython 预发布流程的新滚动版本流的用户。

作为本提案的一部分,beta 版本的用法指导将从“不得用于生产环境”更改为“仅适用于具有足够强大的兼容性测试和操作监控能力的生产环境”。

同样,alpha 版本的指导将修改为“旨在用于库兼容性测试和创建 ABI 兼容的二进制产物”,而不是简单地说“不得用于生产环境”。

PEP 作者认为,通过修改 CPython 的预发布管理流程(如下文“提案”部分所述)可以实现这些结果。

本 PEP 还建议调整 X.Y.0 版本的发布频率,以便在每两年一次的八月份开始新的版本系列(从 2021 年开始,大约在 Python 3.8.0 发布两年后)。

未来发布计划示例

根据此提案,Python 3.9.0a1 将于 2019 年 12 月发布,比 2019 年 10 月发布的 Python 3.8.0 基线功能版本晚两个月。

假设 CPython 完全 ABI 没有进一步的中断性变更,3.9.0b2 版本将在两个月后,即 2020 年 2 月发布,一直到 2021 年 4 月的 3.9.0b9。

任何时候,如果引入了 CPython 完全 ABI 的中断性变更,第一次包含该变更的预发布版本都将被标记为 alpha 版本。

3.9.0rc1 将于 2021 年 6 月发布,3.9.0rc2 于 2021 年 7 月发布,然后完整的版本将作为 3.9.0 于 2021 年 8 月发布。

周期将于 2021 年 10 月重新开始,发布 3.10.0a1(在创建 3.9.x 维护分支 4 个月后)。

维护版本发布的具体时间表将由发布团队决定,但假设 3.9.x 的维护版本也将每隔一个月发布一次(与 3.10.0 beta 版本错开),那么总体发布时间线将如下所示:

  • 2019-12: 3.9.0a1
  • 2020-02: 3.9.0b2
  • … 每隔一个月发布 beta(或 alpha)版本
  • 2021-04: 3.9.0b9
  • 2021-06: 3.9.0rc1 (功能冻结, ABI 冻结, pyc 格式冻结)
  • 2021-07: 3.9.0rc2
  • 2021-08: 3.9.0
  • 2021-09: 3.9.1, 3.8.x (最终 3.8.x 二进制维护版本)
  • 2021-10: 3.10.0a1
  • 2021-11: 3.9.2
  • 2021-12: 3.10.0b2
  • … beta(或 alpha)和维护版本继续交替发布
  • 2023-04: 3.10.0b10
  • 2023-05: 3.9.11
  • 2023-06: 3.10.0rc1 (功能冻结, ABI 冻结, pyc 格式冻结)
  • 2023-07: 3.10.0rc2, 3.9.12
  • 2023-08: 3.10.0
  • 2023-09: 3.10.1, 3.9.13 (最终 3.9.x 二进制维护版本)
  • 2023-10: 3.11.0a1
  • 2023-12: 3.11.0b2
  • … 等等

如果我们假设在 3.9.0a5 和 3.9.0a7 版本中引入了两次额外的 CPython 完全 ABI 中断性变更的预发布版本,那么整体日历将如下所示:

../_images/pep-0605-example-release-calendar.png

图 1. 预发布流程变更对日历的影响。

在此模型中,始终有两个或三个活跃的维护分支,这在这一点上保持了现状。主要区别在于,我们将开始鼓励发布者提供滚动预冻结版本的预编译二进制文件,以及为稳定维护分支提供预编译二进制文件。

../_images/pep-0605-overlapping-support-matrix.png

图 2. 18 个月周期与 24 个月周期的测试矩阵

针对 CPython 完全 ABI 的包发布者,如果选择提供滚动预冻结版本的预编译二进制文件,至少需要构建新的 wheel 存档,从 3.9.0a1 版本发布开始。后续 alpha 版本(例如示例时间表中的 3.9.0a5 或 3.9.0a7 版本)是否需要发布更新的二进制文件,将取决于他们是否确实受到这些后续 alpha 版本中 ABI 变更的影响。

与现状一样,所有希望提供最终版本预编译二进制文件的包发布者都必须在 ABI 冻结日期后构建新的 wheel 存档。与现状不同的是,此日期将通过发布第一个候选版本(Release Candidate)明确标记,并且将在足够早的时间发生,以便发布者有几个月的时间为最终版本做好准备。

未来发布公告示例

如果此 PEP 被接受,用于将更新的预发布管理流程传达给最终用户的主要渠道将是 Python 3.9 的“新增功能”文档和发布公告本身。

本节提供可用于这些目的的文本草稿。

建议的“Python 3.9 新增功能”条目

以下子节将添加到 Python 3.9 的“新增功能”文档中,并从每个 Python 3.9 alpha 和 beta 版本公告中链接。

PEP 605:预发布管理流程变更

PEP 605 所详述,预发布管理流程已更新,以生成一系列滚动 beta 版本,这些版本被认为适用于具有足够强大的集成测试和操作监控能力的生产环境。

在此新的滚动模型下,alpha 和 beta 版本混合在一个称为“预冻结”的组合阶段中。alpha 版本指示 CPython 完全 ABI 的中断,这可能需要重新编译扩展模块或嵌入式应用程序;beta 版本指示与前一个预发布版本完全的二进制兼容性。

与之前的版本不同,积极鼓励发布 3.9.0 alpha 和 beta 版本的预编译二进制文件,因为在 CPython 完全 ABI 冻结之前构建和加载扩展模块时,会设置一个新的预发布 ABI 标志(“p”),以确保所有此类预冻结的扩展模块构建在冻结后的解释器构建中将被忽略。

CPython 完全 ABI 将在 3.9.0rc1 中冻结,预发布标志将从 ABI 标志中删除。预计该版本将在最终 3.9.0 版本发布前 2 个月发布(有关确切目标日期,请参阅 PEP 596 中的发布计划)。

对于应用程序开发人员来说,迁移到滚动版本流提供了机会,可以在下一个稳定版本发布之前积极参与标准库和参考解释器的增强功能的设计和开发。它还提供了在稳定版本发布一年或更长时间之前受益于解释器性能增强的机会。

对于发布预编译 wheel 存档的库开发人员来说,如果项目已经发布了纯 Python wheel(标记为 py3-none-any)或针对稳定 C ABI(标记为 cp38-abi3-<platform> 或早期 CPython 3.x 版本中等效的)的构建,则支持 3.9.x 滚动版本流以及 3.8 稳定版本系列无需采取任何特殊操作。这些相同的 wheel 存档也将可用于后续的 3.9 稳定版本系列。

对于发布针对 CPython 完全 ABI 构建的预编译 wheel 存档的库开发人员来说,3.9 稳定版本系列的二进制文件需要在 CPython 完全 ABI 冻结后构建(即使用 3.9.0rc1 或更高版本)。

这些库的开发人员也可以通过构建 3.9.0a1 版本(或后续 beta 版本)并按正常方式发布结果来选择支持滚动版本流。

在理想情况下,以此方式构建的二进制文件将一直可用到最后一个预冻结版本。但是,如果项目受到预冻结期间 CPython 完全 ABI 的变更影响,则有必要发布一个维护更新,该更新将受影响的二进制文件重新构建,以匹配引入相关接口的 alpha 版本。在这种情况下,应在项目元数据中添加相应的 Python-Requires 条目。例如,如果一个项目受到 3.9.0a5 中引入的 ABI 变更的影响,则应添加的 Python-Requires 条目是:

Python-Requires: >= "3.9.0b6"; python_version == "3.9" and full_python_version != "3.9.0a5"

(此附加元数据确保更新版本不会安装在提供旧版本 ABI 的早期 3.9 系列预发布版本上)

与应用程序开发人员一样,选择支持滚动版本流的库开发人员将有机会在稳定版本锁定多年(或在稳定版本系列中包含临时 API)*之前*,就新 API 设计提供反馈。

3.9.0a1 版本发布公告文本示例

这是 Python 3.9 的第一个预览版本。作为一个 alpha 版本,它旨在用于库和应用程序兼容性测试以及创建 ABI 兼容的二进制产物。不建议在生产环境中使用。

预发布管理流程变更

CPython 已切换到新的预发布管理流程,旨在生成一系列滚动 beta 版本,这些版本被认为适用于具有足够强大的集成测试和操作监控能力的生产环境。有关详细信息,请参阅 Python 3.9 的“新增功能”文档(链接到相关部分)。

与 3.8 相比,3.9 系列的主要新功能

Python 3.9 的许多新功能仍在计划和编写中。在已实现的主要新功能和变更中:

  • (嗨,各位核心开发者或滚动版本流的用户,如果您发现某个重要功能在此列表中缺失,请告知 <发布管理器>。)

Python 3.9 的下一个预发布版本预计为 3.8.0b2,目前计划于 2020-02-02 发布。

3.9.0b2 版本发布公告文本示例

这是 Python 3.9 的第二个预览版本。作为一个 beta 版本,它与之前的 3.9.0a1 版本完全二进制兼容。建议仅用于具有足够强大的集成测试和操作监控能力的生产环境。

(其余内容与 3.9.0a1 公告相同,但会更新已实现的功能,并且下一个预期版本为 3.9.0b3)

3.9.0a5(中期 alpha 版本)发布公告文本示例

这是 Python 3.9 的第五个预览版本。作为一个 alpha 版本,它与之前的 3.9.0b4 版本*不*完全二进制兼容。此版本旨在用于库和应用程序兼容性测试以及创建 ABI 兼容的二进制产物。不建议在生产环境中使用。

3.9.0b4 和 3.9.0a5 之间的 CPython ABI 完全中断性变更

  • PyObject 结构添加了新字段 ob_example
  • PyTypeObject 结构移除了临时字段 tp_example

支持滚动版本流并需要重新编译以恢复二进制兼容性的项目,应在其更新版本中添加以下元数据:

Python-Requires: >= "3.9.0b6"; python_version == "3.9" and full_python_version != "3.9.0a5"

(其余内容与 3.9.0a1 公告相同,但会更新已实现的功能,并且下一个预期版本为 3.9.0b6)

3.9.0rc1 发布公告文本示例

这是 Python 3.9 的第一个候选版本。作为一个候选版本,此版本现在功能完整,CPython 完全 ABI 已冻结,预发布标记已从 ABI 兼容性标志中移除。建议仅用于具有足够强大的集成测试和操作监控能力的生产环境。

准备最终发布 3.9.0

现在 CPython 完全 ABI 已冻结,针对该 ABI 的库开发人员应构建并发布 3.9.x 稳定系列的二进制文件。

尚未针对滚动版本流进行测试的应用程序开发人员,建议测试他们的应用程序,并报告“移植指南”(链接到相关“新增功能”部分)中未提及的任何兼容性回归。

计划于 2021-07-02 发布第二个候选版本,然后于 2021-08-02 发布最终的 3.9.0 版本。

与 3.8 相比,3.9 系列的主要新功能

此版本中的一些主要新功能和变更:

  • (嗨,各位核心开发者或滚动版本流的用户,如果您发现某个重要功能在此列表中缺失,请告知 <发布管理器>。)

动机

当前的 CPython 预发布和发布管理流程是在自动化持续集成和操作监控系统相对不成熟的时代开发的。自那时以来,许多组织已采用部署模型,使其能够在不增加比其他代码更改多多少风险的情况下,集成新的 CPython 功能版本。更新的部署模型,例如轻量级任务专用应用程序容器,也使得在 CI 管道中将应用程序与语言运行时结合起来,然后保持它们在一起,直到整个容器映像随后被更新的映像替换变得更容易。

鉴于外部环境的变化,PEP 602 提议通过将 CPython 功能版本的发布频率从每 18-24 个月增加到每 12 个月,来减少 Python 标准库和 CPython 参考解释器的功能交付延迟。

不幸的是,对于许多组织来说,采用新 Python 版本的成本不会随着版本中变更数量的减少而自动降低,因为主要成本与解决任何已发现的问题无关;主要成本与*搜索*已发现的问题有关。这种搜索可能涉及对软件系统的手动测试、对书面材料的人工审查以及其他活动,这些活动的所需时间与现有系统的规模成比例,而不是与 Python 版本之间的变更数量成比例。

对于第三方库开发人员来说,成本主要与广泛使用的*不同 Python 版本数量*有关。这目前往往受到 Python-dev 维护哪些版本以及特定分发者提供哪些最新版本(Debian、Ubuntu LTS 和 RHEL/CentOS 系统 Python 版本尤其流行)的组合影响。除了针对更多 Python 版本进行测试的基本 CI 成本外,更多版本被广泛使用会使得确定故障报告是项目中的实际错误,还是报告用户环境中的问题变得更加困难。

PEP 602 提议受影响的组织和项目简单地改为采用每两个或三个 CPython 版本,而不是尝试采用每个版本,但这带来了自己的一系列新问题需要解决,无论是实际的(例如,如果我们期望用户定期跳过版本,那么弃用需要覆盖一个以上版本)还是文化的(例如,随着更多版本被积极使用,开源库维护者收到仅发生在他们自己不使用的 Python 版本上的错误报告的可能性会大大增加)。

PEP 598 是本 PEP 作者之一最初提出的一个替代方案,旨在通过采用语义版本控制风格的策略来减少功能交付延迟,该策略允许在版本系列中增量交付向后兼容的功能,直到该系列达到功能完整状态。该方案仍然具有一个不利的后果,即对对当前版本管理模型感到满意的使用者产生可见的变更。

本 PEP 认为,PEP 598PEP 602 存在一个共同的缺陷:它们试图在单一版本模型中满足两个非常不同受众的需求,这会导致设计要求冲突,以及在这些冲突要求之间做出尴尬的权衡。本 PEP 中的提案旨在通过创建两个*独立*的生产就绪版本流来避免这一缺陷,现有版本流基本保持不变,而新版本流则针对最能从减少功能交付延迟中受益的受众进行定制。

本提案的目标

本 PEP 中的提案基于以下关键假设:

  • 绝大多数 Python 用户并不积极要求新的语言和运行时级别功能,而是仅在他们之前使用的版本不再受支持、他们的 Python 提供商默认切换到提供更新版本、或者足够多的他们感兴趣的变更累积到足以构成升级的令人信服的理由时才进行升级。
  • 对于新版本的许多用户来说,采用新版本时出现的大部分工作不是源于语言级别的兼容性问题,而是源于组件安装级别的兼容性问题(例如,文件名和安装路径的变更)。
  • 有一部分 Python 用户愿意在生产环境中运行生产就绪的预发布版本(类似于 Windows Insider 或 Debian 测试版本),至少用于部分用例。

本 PEP 提案的核心是通过生成一个定期的增量功能版本滚动流来改变 CPython 预发布流程,并确保这些构建的大多数提供足够的稳定性,使其适用于适当管理的生产系统。

通过采用这种方法,该提案旨在为几乎所有 Python 用户和贡献者提供改进的结果:

  • 对于新增量功能版本流的用户,瞄准预发布阶段可以实现比 PEP 602 中提出的年度发布周期更低的延迟。
  • 对于从事新功能开发的 CPython 核心开发人员来说,预发布的频率增加和采用率提高应该能够改进预发布反馈周期。
  • 对于稳定版本流的用户来说,在预发布期间采用率的提高和反馈周期的改进应该能够提高其第一个 X.Y.0 版本发布时的功能成熟度,以及提高生态系统的就绪程度。
  • 对于 Python 库维护人员来说,滚动发布的预发布版本流有望提供比当前预发布管理流程更多的机会,以便在功能发布到完整稳定版本之前识别和解决设计问题;以及
  • 对于替代 Python 实现的开发人员来说,滚动预发布版本流可能为扩展模块作者提供额外的动力,将其从 CPython 完全 ABI 迁移到 Python 稳定 ABI,这也将使更多生态系统与不模拟 CPython 完全 C API 的实现兼容。

尽管如此,但也承认并非本提案的所有成果都将惠及更广泛的 Python 生态系统的所有成员:

  • 对于 Python 库维护人员来说,本 PEP 和 PEP 602 都可能导致用户压力,要求支持更快的发布周期。虽然本 PEP 试图通过明确标记哪些预发布版本包含 CPython 完全 C ABI 的潜在中断性变更来缓解此问题,PEP 602 则试图通过将完整版本之间的最小时间保持在 12 个月来缓解此问题,但无法完全消除此缺点;
  • 对于第三方扩展模块维护人员来说,本 PEP 和 PEP 602 都可能导致用户压力,要求开始支持稳定 ABI,以便为新版本提供即时可用的 wheel 存档。这是否是净负面影响,将取决于请求如何呈现给他们(如果请求是以一种礼貌的贡献形式,来自有兴趣支持滚动预冻结版本的开发人员,那么这可能是一个积极的方面);
  • 对于一些依赖于预编译 wheel 存档可用性的稳定版本流用户来说,切换到每 12 个月采用一次新版本可能是一个可接受的增加率,而持续转向历史 18-24 个月周期的 24 个月末端将是相对于近期版本使用的 18 个月周期而言不理想的降低率。此提案对这些用户的净负面影响将取决于我们是否能够说服库维护人员,让他们觉得值得在 API 和 ABI 冻结之前就支持即将发布的稳定版本,而不是等到 API 和 ABI 冻结。

提案

本 PEP 中提议的大部分变更仅影响预发布版本的处理。唯一影响完整版本发布的变更建议是调整其发布周期。

稳定版本每两年发布一次

由于滚动预冻结版本可供希望使用参考解释器和标准库的最新版本用户使用,本 PEP 提议将 X.Y.0 版本发布频率调整为每两年一次在八月份发布新稳定版本(从 2021 年开始,大约在 Python 3.8.0 发布两年后)。

这一变更可能与拟议的预冻结发布期处理变更正交,但联系在于,如果没有这些预发布管理变更,两年一次完整发布周期的缺点可能会大于优点,而对于 12 个月发布周期而言,情况则相反(即,有了本 PEP 中提出的预发布管理变更,12 个月完整发布周期的缺点将大于优点)。

将 alpha 和 beta 阶段合并为“预冻结”阶段

本 PEP 提议,而不是继续现状(即预发布 alpha 和 beta 阶段是独立的、顺序的),而是将它们合并为一个单一的“预冻结”阶段,并对版本使用单调递增的序列号。

“alpha”和“beta”名称将不再表示不同的阶段,而是指示该版本是否包含 CPython 完全 ABI 的中断性变更。

  • “alpha”版本将是“ABI 中断”版本,其中基于前一个预发布版本构建的 CPython 完全 ABI 的扩展模块不一定能够正确加载。
  • “beta”版本将是“二进制兼容”版本,其中基于前一个预发布版本构建的 CPython 完全 ABI 的扩展模块预计能够正确加载,前提是这些模块符合以下附加标准:
    • 模块不得使用上一个稳定版本系列或开发中的预发布系列中已删除或以 ABI 不兼容方式更改的任何临时或私有 C API。
    • 模块不得使用上一个稳定版本系列中已弃用并在此 beta 版本中删除的任何 C API。

预冻结阶段的持续时间和节奏

预冻结版本将始终稳定地每两个月发布一次,而不是在准备新的 X.Y.0 版本期间每月发布一次,持续几个月。

唯一例外情况是在即将发布的 X.Y.0 版本为期两个月的候选发布(Release Candidate)期间(有关更多详细信息,请参阅下文的候选发布部分)。这意味着将跳过两个计划中的发布(一个对应第一个候选发布日期,一个对应最终发布日期)。

预冻结阶段通常预计在 preceding 稳定 X.Y.0 版本发布后 2 个月开始。

任何新版本系列的第一个预冻结版本始终是 X.Y.0a1(因为没有具有相同 ABI 版本标记的前版本可用于判断二进制兼容性)。

预冻结版本将在其 C ABI 兼容性标记中添加一个额外的标志,以避免与最终稳定版本产生二进制兼容性问题。

beta 版本发布策略

本 PEP 提议 beta 版本的策略如下:

  • 与当前 beta 版本一样,预计在准备和发布 beta 版本之前,稳定的 BuildBot 队列将保持绿色。
  • 与当前 beta 版本一样,发布管理器预计将在准备和发布 beta 版本之前审查打开的发布阻塞问题。
  • 与当前 beta 版本一样,预计 abi3 稳定 C ABI 的任何添加都将成为该 ABI 的永久组成部分,除非并直到该稳定 ABI 版本完全退役(注意:目前没有计划增加稳定 ABI 版本)。
  • 与当前 beta 版本不同,本 PEP 下的 beta 版本*不*会被视为下一个 X.Y.0 版本的完整功能。
  • 与当前 beta 版本不同,所有自上次 CPython 功能版本以来添加的 API(稳定 C ABI 的添加除外)都将被视为临时性的。
  • 与当前 beta 版本不同,本 PEP 下的 beta 版本将从主开发分支准备和发布。
  • 与当前 alpha 或 beta 版本不同,本 PEP 下的 beta 版本必须与系列中紧接的前一个预发布版本完全 ABI 兼容(排除对临时 API 的更改或删除在前一个版本系列中已弃用的 API)。

alpha 版本发布策略

本 PEP 提议 alpha 版本的策略如下:

  • 与当前 alpha 版本一样,预计在准备和发布 alpha 版本之前,稳定的 BuildBot 队列将保持绿色。
  • 与当前 alpha 版本一样,发布管理器预计将在准备和发布 beta 版本之前审查打开的发布阻塞问题。
  • 与当前 alpha 版本不同,即使是 alpha 版本,发布管理器也应目标达到与当前 beta 版本相似的稳定性级别。

根据本 PEP,当无法发布满足 beta 版本标准的版本时,并且允许额外的时间也无法解决问题时,就会发布 alpha 版本。

预计 CPython 完全 API 的中断性变更(例如,在公共结构定义中添加或删除字段)将是发布额外的 alpha 版本(除了定义 X.Y.0a1 版本的初始兼容性标签之外)的最可能原因,但任何特定版本的决定权在于发布管理器。

候选发布(Release Candidate)策略、阶段持续时间和节奏

鉴于 alpha 和 beta 发布阶段的拟议变更,候选发布阶段将看到以下相关调整:

  • 功能冻结、ABI 冻结、pyc 文件格式冻结和维护分支创建都将与 X.Y.0rc1 的创建同时发生(目前这些发生在 X.Y.0b1、最后一个 beta 版本和 X.Y.0rc1 之间)。
  • X.Y.0 版本候选发布期将从 3 周延长至 2 个月。
  • 通常会每月发布两个候选版本,但发布管理器可以自行决定发布额外的候选版本。
  • 最终的 X.Y.0 版本将在最后一个候选版本发布后 1 到 4 周内发布(取决于第二个之后是否需要额外的候选版本)。
  • 如果最终的 X.Y.0 版本延迟到八月目标日期之后,后续版本系列不受影响,仍将安排在八月(现在比原计划的两年少一点)。

除了为最终用户提供更多时间反馈候选版本外,这一调整后的策略还为 Python 项目的维护者提供了更多时间来构建和发布新稳定版本的预编译 wheel 存档,从而显著改善 X.Y.0 版本的初始用户体验。

CPython 稳定 ABI 管理变更

CPython 稳定 ABI [5] 承诺,使用特定 CPython 版本构建的二进制扩展模块将在支持相同稳定 ABI 版本的未来 CPython 版本中继续工作(该版本当前为 abi3)。

根据提议的滚动预冻结版本模型,此承诺也将适用于 beta 版本:一旦即将发布的 Python 版本的 abi3 稳定 ABI 的有意添加在 beta 版本中发布,那么只要 abi3 稳定 ABI 仍然受支持,它就不会从未来的版本中移除。

将提供两个主要机制来获取对稳定 ABI 添加的社区反馈:

  • 首选机制是将新 API 添加到 CPython 完全 API 中,并在至少一个发布的 beta 版本中包含该 API 并获得相关用户反馈后,再将其提升到稳定 ABI。
  • 对于由于某种原因(例如,某些 API 添加在 CPython 完全 API 可用时没有用处)无法采用该方法的 API,开发人员可以请求发布管理器将下一个版本标记为 alpha 版本(即使 CPython 完全 ABI 没有中断),并尝试通过这种方式获得进一步反馈。

为了提高可读性和可用性,本 PEP 还提议为每个主要的稳定 ABI 版本引入别名。

#define Py_LIMITED_API_3_3 0x03030000
#define Py_LIMITED_API_3_4 0x03040000
#define Py_LIMITED_API_3_5 0x03050000
#define Py_LIMITED_API_3_6 0x03060000
#define Py_LIMITED_API_3_7 0x03070000
#define Py_LIMITED_API_3_8 0x03080000
#define Py_LIMITED_API_3_9 0x03090000
// etc...

这些将用于扩展模块代码中设置目标 ABI 版本,

#define Py_LIMITED_API Py_LIMITED_API_3_8

以及用于 CPython 解释器实现中检查哪些符号应可用。

#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= Py_LIMITED_API_3_9
// A Python 3.9+ addition to the stable ABI would appear here
#endif

滚动预冻结版本的文档和稳定 C ABI 将明确指出,使用后期预冻结版本中稳定 ABI 构建的扩展模块在早期预冻结版本上可能无法正确加载。

alpha 版本和稳定 C ABI 的文档将明确指出,即使是使用 alpha 版本中稳定 ABI 构建的扩展模块,如果连续发布了两个 alpha 版本,在下一个版本上也可能无法正确加载(这种情况理想情况下应该很少见)。

CPython 完全 ABI 管理变更

本 PEP 提议对 CPython 完全 ABI 的管理进行两项变更。

标记 ABI 中断性变更的提交和 NEWS 文件约定

本 PEP 的提案要求发布管理器能够根据预冻结版本是否包含 ABI 中断性变更,将其适当地标记为 alpha 或 beta 版本。

为协助此过程,核心开发人员将被要求在所有 NEWS 文件片段的开头包含“(CPython ABI break)”标记,用于介绍引入 CPython 完全 C ABI 中断性变更的内容。

包含“CPython”标记是为了明确这些注释与完全 CPython ABI 相关,而不是与稳定 ABI 相关。

对于提交消息,较短的标记“(ABI break)”将放置在提交的摘要行开头。

预合并机器人将被更新,以确保如果 ABI 中断标记出现在这两个位置中的一个,则也出现在另一个位置。

如果标记无意中从初始提交消息和 NEWS 条目中遗漏,那么在添加标记到 NEWS 条目的后续提交中应包含提交消息标记。

除了对发布管理器有用外,这些标记对于调查在受影响版本上测试时出现的意外分段错误(segfault)的开发人员也应该有用。

明确标记基于预冻结 ABI 的构建

CPython 完全 ABI 长期以来一直遵循一项政策,即二进制兼容性仅在 ABI 被宣布冻结后在一个版本系列内适用,而不同版本系列之间只适用源代码兼容性。

此政策意味着,在 ABI 冻结日期之前使用 CPython 预发布版本构建的扩展模块,在最终版本上可能无法正确加载。

这是因为扩展模块可能依赖于在后续 alpha 或 beta 版本中已更改或删除的临时或先前已弃用的接口,或者它可能是由于用于扩展模块的公共结构因添加新字段而改变了大小。

历史上,alpha 和 beta 版本的采用率足够低,以至于这在实践中并没有真正成为一个问题。然而,本 PEP 提议积极鼓励 beta 版本在生产环境中的广泛使用,因此希望确保这些版本的用户不会无意中发布二进制扩展模块,从而导致运行候选版本和最终版本的用户出现分段错误。

为此,本 PEP 提议在非 Windows 系统上修改扩展模块 SOABI 标记,以包含一个新的“p”标志用于 CPython 预发布版本,并且只有在特定 X.Y.0 版本的 ABI 已在进入候选发布阶段时冻结后,才恢复为省略该标志。

通过此更改,3.9.0 的 alpha 和 beta 版本将获得 SOABI 标签 cpython-39p,而所有候选版本和最终构建(无论是 3.9.0 还是后续的 3.9.x 版本)将获得未加标记的 SOABI 标签 cpython-39

调试构建仍将在标签末尾添加“d”,为预发布版本的调试构建提供 cpython-39pd

在 Windows 系统上,预发布构建中标记的 pyd 文件的后缀将在版本号之后立即包含“p”作为预发布标记,提供类似“cp39p-win_amd64”的标记。

此变更的拟议参考实现可在 [4] 找到(注意:撰写本文时,该实现尚未在 Windows 上进行测试)。

更新受完全 ABI 变更影响的项目所需的 Python 版本

当一个项目首次选择为滚动预冻结版本系列提供预编译二进制 wheel 时,它们不需要做任何特殊的事情:它们会将滚动版本系列添加到其构建和测试矩阵中,并发布标记为与该版本系列兼容的二进制存档,就像它们在该版本系列的 CPython 完全 ABI 冻结后提供预编译二进制 wheel 一样。

但是,如果项目受到滚动版本流中 CPython ABI 兼容性中断的影响,那么它们需要发布一个版本更新,该更新包括新的二进制构建和新的环境约束 Python-Requires 标记。

例如,如果一个支持滚动版本流的项目受到了 3.9.0a5 版本中 CPython ABI 兼容性中断的影响,那么它们将在发布更新二进制版本的版本中添加以下元数据条目:

Python-Requires: >= "3.9.0b6"; python_version == "3.9" and full_python_version != "3.9.0a5"

这会做什么?它在发布的包中添加了一个额外的兼容性约束,因此 3.9.0 beta 版本(早于 3.9.0b6)将不会将更新的包视为安装候选,并且唯一会考虑该包的 alpha 版本是 3.9.0a5 本身。

注意事项和限制

实际发布日期最多可能提前或推迟一个月,由发布管理器根据发布团队的可用性以及其他事件(例如 PyCon US 或年度核心开发冲刺)的时间来决定。但是,由于该提案的目标之一是提供一致的发布周期,因此调整应该是罕见的。

在一个版本系列中,维护版本的确切发布频率仍然由发布管理器和二进制发布团队决定;本 PEP 仅提议了预发布版本和 X.Y.0 版本的预期发布周期。

但是,为了示例时间线的目的,PEP 假设维护版本每隔一个月发布一次,允许它们与滚动预冻结版本交替发布。

发布管理器和指导委员会还将保留修改本 PEP 中各项提案细节的权力。可能的修改包括(但不限于):

  • 更改维护分支的创建时间。如果一个需要新 alpha 版本的主要变更在预发布流程的后期才合并,发布管理器可能会选择从该主要变更之前的点分叉。例如,如果下一个计划发布的版本是最终 beta 版本或第一个候选版本,这样做可能是合理的。
  • 将声明 alpha 版本的标准可能扩展到包括所有需要“移植”条目到“新增功能”文档中的变更。
  • 发布管理器可以预先宣布一些日期为 alpha 版本,并要求核心开发人员相应地安排他们的风险较高的变更,而不是按需声明 alpha 版本。

PEP 中具体提案的目的是提供一个清晰的说明性示例供审阅者考虑,而不是限制我们根据该流程的实际经验来调整具体细节的能力。

设计讨论

为何选择滚动预冻结版本而不是简单地进行更频繁的 X.Y.0 版本发布?

对于 Python 的大部分用户来说,新 CPython 功能版本*的可用性*并不是他们采用这些新版本的限制因素(这一影响在 PyPI 下载元数据等指标中可见)。

因此,任何基于加速完整功能发布频率的提案都需要在满足每个版本发布时都进行采纳的用户需求,以及那些现在将处于采用每 2 个、3 个或 4 个版本,而不是在其生命周期内的某个点几乎能够迁移到每个版本的情况的用户需求之间取得平衡。

本提案旨在从不同角度解决问题,即定义一个*新的*生产就绪版本流,该版本流更专门地针对那些能够以 CPython 核心团队准备生成的速度消耗新版本的操作环境。

是否必须保留“alpha”和“beta”命名方案?

使用拟议的滚动版本的前“a”和“b”初始字母,是 CPython 版本号发布方式的一些实际方面所强制的设​​计约束。

具体来说,alpha 版本、beta 版本和候选版本在某些地方使用字符串“a”、“b”和“c”表示,而在其他地方则使用十六进制数字 0xA0xB0xC 表示。我们希望保留这一点,同时确保任何 Python-Requires 约束都是针对 beta 版本而不是 alpha 版本(因为后者在连续发布两个 alpha 版本时可能无法强制执行 abi3 稳定性要求)。

然而,没有什么能强迫我们说“a”代表“alpha”或“b”代表“beta”。

这意味着,如果我们想增加那些仅因“beta”标签而犹豫的人的采用率,那么强调“*A*BI 中断”和“*B*inary 兼容”的名称而不是“alpha”和“beta”的名称可能会有意义,例如:

  • 3.9.0a1:ABI 中断的预冻结版本
  • 3.9.0b2:二进制兼容的预冻结版本
  • 3.9.0rc1:候选版本
  • 3.9.0:最终版本

本 PEP 的当前迭代并未走那么远,因为将滚动预冻结版本的初始采用限制在那些对“beta”标签感到满意的人身上可能是一件好事,因为这些版本的早期采用者将遇到更广泛的 Python 生态系统中出现的任何意外后果,我们需要他们愿意积极参与解决这些问题。

因此,假设结果足够积极,以至于我们认为这种方法值得继续,那么未来可以考虑放弃“beta”命名。

为何选择滚动预冻结版本而不是在稳定和不稳定版本系列之间交替?

使用滚动版本而不是 beta 周期,另一种选择是传统稳定版本(用于 3.8.x、3.10.x 等)和使用新滚动版本周期的版本系列(用于 3.9.x、3.11.x 等)之间交替。

这个想法存在与 PEP 598PEP 602 相同的核心问题:它对对现状感到满意的使用者施加了变更,而没有提供任何明确的补偿性好处。

它还受到反对 PEP 598 的主要担忧之一的影响:至少一些核心开发人员和最终用户强烈认为,不应为版本号的*值*分配任何特定的语义。这些社区成员反而认为,所有语义意义都应与版本号中改变的*位置*相关联。

相比之下,滚动预冻结版本提案旨在通过确保拟议的政策变更都围绕特定版本是 alpha 版本、beta 版本、候选版本还是最终版本来解决这一担忧。

为何不为滚动发布流使用日历版本控制?

Steve Dower 的初始提案撰写 [1] 建议对滚动版本流使用日历版本控制(因此,Python 3.8.0 之后的第一个滚动预发布版本将是 Python 2019.12 而不是 3.9.0b1)。

Paul Moore 指出了 [2] 该提案的两个主要实际问题:

  • 用户将无法清楚地了解基于日历的版本与传统编号版本之间的关系。
  • 它破坏了 Python-Requires 元数据在打包工具中的处理,并且没有明确的方法可以可靠地修复它(因为所有日历版本都将比任何标准版本看起来都新)。

本 PEP 旨在通过使用已建立的 beta 版本号来解决这两个问题,用于滚动版本。

例如,考虑以下问题:“Python 2021.12 是否包含 Python 3.9.0 中发布的所有新功能?”。使用滚动版本的日历版本控制,无法回答此问题,除非查阅发布日历以了解 3.9.0rc1 何时从滚动版本流中分叉。

相比之下,滚动预冻结版本的等效问题很容易回答:“Python 3.10.0b2 是否包含 Python 3.9.0 中发布的所有新功能?”。仅从问题的措辞就可以清楚地得出答案:“是的,除非它们是已删除的临时功能”。

beta 版本编号方法也避免了日历版本控制概念提出的其他问题,例如 sys.version_infoPY_VERSION_HEXsite-packages 目录命名以及安装的 Python 二进制和扩展模块命名将如何工作。

滚动预冻结版本的用户如何检测 API 变更?

在添加新功能时,将大力鼓励核心开发人员通过不依赖于 sys.version_info 或运行时代码对象内省的机制来支持功能检测和优雅回退到替代方法。

在大多数情况下,对受影响模块进行简单的 hasattr 检查即可达到此目的,但当不满足时,将作为功能添加的一部分考虑替代方法。此领域的先例包括 pickle.HIGHEST_PROTOCOL 属性、hashlib.algorithms_available 集合以及 os 模块已为平台特定功能检测提供的各种 os.supports_* 集合。

还可以添加需要在使用滚动预冻结版本中首次包含时通过 __future__ 导入显式启用的功能,即使该功能标志随后在 X.Y.0 版本候选发布首次出现之前默认启用。

这些方法的理由是,显式检测/启用(例如 from __future__ 导入如果功能标志不再存在,则会在编译时中断)将使滚动预冻结版本流的用户能够轻松地注意到我们何时删除或更改临时功能,或者安全地回退到先前的功能。

解释器丰富的属性查找机制意味着我们还可以选择为临时或已弃用的导入和属性添加警告,而我们无法通过检查 sys.version_info 的值来处理这些情况。

为何要添加新的预冻结 ABI 标志来强制在 X.Y.0rc1 之后重新编译?

CPython 核心开发团队目前积极*不鼓励*在 ABI 冻结日期之前创建 X.Y 系列的公共预编译二进制文件。

我们这样做的原因是避免在稳定 X.Y.0 版本上出现痛苦的调试会话,这些会话追溯到“哦,我们的依赖项‘superfast-binary-operation’受到了 X.Y.0a3 中 CPython ABI 中断的影响,但该项目自那以后没有发布新版本”。

通过在 CPython X.Y 版本系列上启用提议的预冻结 ABI 标志,此发布采用过程的这一方面基本保持不变:新的 CPython X.Y 版本系列达到 ABI 冻结 -> 包维护者为该版本系列发布新的二进制扩展模块 -> 最终用户仅因实际错误而遇到分段错误,而不是仅仅因为构建与不兼容的 ABI 相关。

新的预冻结 ABI 标志的主要目标是改善滚动预冻结版本本身的体验,允许为这些版本发布预编译二进制存档,而不会冒着目前导致我们积极不鼓励在 ABI 冻结之前发布二进制产物的风险。

在理想情况下,包维护者只需在 X.Y.0a1 版本发布一个预冻结二进制构建,然后在 X.Y.0rc1 之后发布一个冻结后构建。在此期间仅*需要*重建的情况仅限于项目实际受到中间 alpha 版本中 ABI 中断的影响。

例如,考虑一种情况,我们最终有三个版本包含 ABI 中断:X.Y.0a1、X.Y.0a5、X.Y.0a7。然后,X.Y.0a7 的 ABI 将贯穿所有后续的 beta 版本并进入 X.Y.0rc1。(这是图 1 中说明的情况)

强迫每个人在滚动版本流中的每次 alpha 版本发布时都重建整个世界,几乎肯定会导致发布者认为支持滚动版本弊大于利,因此我们希望允许将使用 X.Y.0a1 构建的模块加载到 X.Y.0a7 上,因为它们*可能*是兼容的(很少有项目会使用 CPython 发布的所有 C API,并且大多数 ABI 中断只会影响单个特定 API)。

然而,一旦我们发布了 X.Y.0rc1,我们就希望确保那些使用 X.Y.0a1 和 X.Y.0a4 构建的二进制文件完全从最终用户体验中移除。虽然能够保留 X.Y.0a7 及后续 beta 版本(因为事实证明那些实际上是针对冻结后 ABI 构建的,即使当时我们不知道)的构建是好的,但丢失它们并不会比现状*更糟*。

这意味着预冻结标志是“最简单的可能工作的”来解决这个问题——它只是一个新的 ABI 标志,我们已经拥有处理 ABI 标志的工具(无论是在解释器中还是在包发布和安装工具中)。

由于 ABI 标志相对于预发布版本发生了变化,项目甚至不需要发布新版本:它们可以将新的 wheel 存档上传到其现有版本中,就像今天一样。

虽然一个更巧妙的方案,能够追溯接受所有在最后一个 alpha 版本或后续 beta 版本上构建的内容,但对于采用本 PEP 来说,它并不被认为*必需*,因为即使我们最初采用简单的预发布 ABI 标志,未来仍然可能设计出更复杂的方案。

为何允许在 X.Y.0a1 之后发布其他 alpha 版本?

在理想情况下,CPython 完全 ABI 的所有中断性变更都将在 X.Y.0a1 版本中与文件系统布局变更一起出现,并且该版本系列的 ABI 将从此保持稳定。

然而,最近的历史表明,我们无法真正做出这一承诺并坚持下去,因此 PEP 假设 ABI 变更将在预冻结期间逐步进行,并且在准备 X.Y.0rc1 时创建 X.Y.z 维护分支时才会进行完全锁定。

对 CPython 核心开发的影响

CPython 核心开发的主要变化是需要使主分支更稳定地为发布做好准备。

虽然主要要求是保持稳定的 BuildBot 队列绿色,但也会鼓励保持开发版本的文档最新,以造福滚动预冻结版本的用户。这将包括为已实现的功能提供“新增功能”条目的草稿,尽管初始版本可能相对稀疏,然后根据 beta 版本用户的反馈进行扩展。

对于从事 CPython C API 开发的核心开发人员,还将需要一致地在其 NEWS 文件片段中标记 ABI 中断性变更。

关于稳定 ABI 的具体主题,大多数 API 设计都可以通过一个过程,首先将其作为 CPython 完全 API 的临时部分引入(允许在预冻结版本之间进行更改),并在开发人员确信接口确实稳定后,再将其提升到稳定 ABI。

只有在 API 在稳定 ABI 之外没有用处等罕见情况下,才可能发布包含临时稳定 ABI 添加的 alpha 版本,而不是在 CPython 临时 API 中迭代设计。

对 Python 库开发的影响

如果本 PEP 成功实现了其目标,那么对于库作者来说,支持滚动预冻结版本流的痛苦程度将不会比支持稳定版本大多少。

对于纯 Python 包的发布者来说,这将是发布标记为“py3”的 wheel 存档,并且可能将滚动预冻结版本流添加到他们的测试矩阵中,如果该选项可用的话。

对于二进制扩展模块的发布者来说,首选选项是(如果可行)瞄准稳定 C ABI,从而获得与纯 Python 包类似的体验,即一个预编译的 wheel 存档可以覆盖多个 Python 版本,包括滚动预冻结版本流。

此选项并非对所有库都可行,并且对于那些作者来说,期望他们通过构建和发布一个额外的 wheel 存档来支持滚动版本,该存档是在初始 X.Y.0a1 版本上构建的。然后,在 X.Y.0rc1 或更高版本上的后续构建与仅支持最终稳定版本所需的构建相同。

此后,只有在该特定库受到这两个点之间发生的任何其他 alpha 版本中的 ABI 中断直接影响的情况下,才需要额外的 wheel 构建。

提供一个滚动预冻结版本流也可能使更多的 CI 提供商能够提供“CPython beta 版本”测试选项。目前,只有那些愿意并有能力投入必要的时间和精力来创建、测试和发布 CPython 主分支的构建的 CI 提供商才能使用此功能(例如,[6])。

对拟议的科学 Python 生态系统支持期的影响

基于 SciPy 2019 的讨论,已经起草了 NEP(NumPy 增强提案)29 [3],以在科学 Python 生态系统中提出一个通用的约定,用于停止支持旧的 Python 版本。

虽然该策略的确切表述仍在讨论中,但草案提案(截至 2019 年 10 月 20 日)建议项目支持过去 42 个月内发布的任何 Python 功能版本,最低要求是支持最新的 2 个 Python 功能版本。

对于 18 个月的功能发布周期,这意味着始终至少支持最近的两个功能版本,然后在 X.(Y+2).0 发布后大约 6 个月内停止支持所有 X.Y.Z 版本。这意味着大约每两年会有 6 个月的窗口期,在此期间支持三个最近的功能版本。

对于 12 个月的功能发布周期,这意味着始终至少支持最近的三个功能版本,然后在 X.(Y+3).0 发布后大约 6 个月内停止支持所有 X.Y.Z 版本。这意味着每年的前半部分将支持四个最近的功能版本,后半部分有望用于准备当年的功能版本。

对于 24 个月的功能发布周期,第二个条款优先于第一个条款,并且为了持续支持两个最近的 CPython 功能版本,建议的 Python 版本支持期从最初的 X.Y.0 版本发布起延长至 48 个月。对于也支持滚动版本流的项目,支持的功能版本数量将增加到三个。

核心开发冲刺(sprint)的发布周期对齐

通过本 PEP 的提案,预计核心开发冲刺的重点将根据两年周期中的当前位置略有转移。

在发布年份,PyCon US 的时间适合新贡献者在第一个候选版本发布之前处理错误修复和小型功能,而语言峰会和核心开发人员的讨论可以专注于下一个版本系列的计划。

发布年份的预 alpha 核心开发冲刺将提供一个机会,将前一个版本收到的反馈纳入其中,无论是作为下一个维护版本(用于错误修复和对临时 API 的反馈),还是作为下一个版本系列(用于对稳定 API 反馈)的第一个 alpha 版本。

这些初始 alpha 版本也将是 CPython 完全 ABI 的 ABI 中断性变更的首选目标(尽管如本 PEP 中所述,在此发布周期的后期仍然允许进行变更,但将其合并到 X.Y.0a1 版本意味着它们不会给预编译二进制包的发布者带来额外的工作)。

下一个发布周期的指导委员会选举也很可能在预 alpha 开发冲刺的同时进行。

在非发布年份,这两个活动的重点将仅限于即将到来的维护和预冻结版本。这些不太紧张的年份有望提供机会来处理各种流程变更和基础设施升级,而不会影响候选发布准备过程。

主流 Linux 发行版的发布周期对齐

一些滚动发布的 Linux 发行版(例如 Arch、Gentoo)可能能够使用本 PEP 提议的新滚动预冻结版本,但预计大多数发行版将继续使用已发布的版本。

本 PEP 中为最终发布提议的具体日期选择是为了与 Ubuntu 和 Fedora Linux 发行版每年十月发布的日期冻结计划保持一致。

对于 Fedora 和 Ubuntu 来说,这意味着候选发布阶段与发行版发布的开发周期一致,这是他们测试新版本并提供有关潜在回归和兼容性问题的反馈的理想时间。

对于 Ubuntu 来说,这意味着他们的四月 LTS 版本将受益于使用新系统 Python 版本的完整短期发布周期,同时该 CPython 版本在其发布到下一个 Ubuntu LTS 版本之前的大部分时间都可以进行上游错误修复。

与本 PEP 中的具体提案可能一直不佳的 Linux 发布周期对齐是 Debian,因为它自 2005 年以来一直在奇数年份的上半年发布(大致偏移 Ubuntu LTS 版本 12 个月)。

根据 PEP 602 中的年度发布提案,Debian 和 Ubuntu 都将始终获得大约 6 个月大的系统 Python 版本,但彼此之间也会选择不同的 Python 版本。

对于两年周期,并且 CPython 版本在下半年发布,它们很可能选择相同的版本,但其中一个将选择一个比最新的 beta 版本晚 18 个多月的 CPython 版本,直到 Linux 发行版发布。

如果这种情况发生,并且被认为是不理想的(但又不至于让*Debian*选择调整其发布时间),那么 PEP 598 中的“增量功能发布”提案的额外复杂性可能会变得有价值。

(将 CPython 版本移动到与 Debian 和 Ubuntu LTS 发布相同的半年期可能有助于缓解问题,但也会产生新问题,即 CPython 发布时间表的延迟可能会直接影响 Linux 发行版的发布时间表,或者导致发行版发布一个比最新的 beta 版本晚 18 个多月的 Python 版本)。

对简单部署环境的影响

就本 PEP 而言,“简单”部署环境是指任何易于确保所有目标环境同时更新到新 Python 版本(或至少在更高层应用程序版本发布之前)的用例,并且任何预发布测试仅需要针对单个 Python 微版本。

最简单的此类情况是脚本的个人使用,此时测试和目标环境完全相同。

同样简单的环境是容器化 Web 服务,其中 CI 管道中使用的 Python 容器与部署中使用的相同,以及任何捆绑自己 Python 运行时而不是依赖于目标系统上已有的 Python 部署的应用程序。

对于这些用例,有一种直接的机制可以最大限度地减少此 PEP 的影响:继续使用稳定版,并忽略滚动式预冻结版。

要在这些环境中实际采用滚动式预冻结版,主要挑战将是如何处理扩展模块段错误的可能性,当下一版预冻结版是 alpha 版而不是 beta 版时,这表明 CPython ABI 可能发生了不兼容的更改。

如果所有使用的扩展模块都以稳定 ABI 为目标,那么就没有问题,一切都会像稳定版一样顺利运行。

或者,“重新构建和重新缓存所有扩展模块”可能成为更新到 alpha 版时进行的标准活动。

最后,直到出现问题为止都不去担心它,然后像处理新 alpha 版或 beta 版中发现的任何其他库兼容性问题一样来处理它,也是合理的。

除了扩展模块 ABI 兼容性之外,使用滚动式预冻结版时产生的其他主要额外复杂性将是独立版本化功能(如 pickle 和 SQLite)的“回滚”兼容性,其中使用 beta 流中的新功能或临时功能可能会创建稳定版无法读取的文件。使用这些类型的功能并还需要能够可靠地回滚到以前的稳定 CPython 版本,像今天一样,建议避免采用预发布版本。

对复杂部署环境的影响

就本 PEP 而言,“复杂”部署环境是指不符合上述“简单部署”标准的用例。它们可能涉及多个不同的 Python 版本,使用个性化的 Python 构建,或者需要“看门人”在部署前批准新版本的使用。

例如,将 Python 作为标准操作系统环境的一部分安装在其用户机器上的组织属于此类,提供标准构建环境的组织也是如此。像 conda-forge 或 WinPython 这样提供一致构建和验证的软件包集合的发行版也受到类似方式的影响。

这些组织倾向于偏爱高稳定性(例如,所有那些愉快地使用稳定 Linux 发行版(如 Debian、RHEL/CentOS 或 Ubuntu LTS)中的系统 Python 作为其首选 Python 环境的人)或快速周转(例如,那些经常为最新 CPython 预发布版做出贡献的人)。

在某些情况下,同一组织中可能为了不同的目的而存在这两种使用模式,例如

  • 为任务关键型系统使用稳定的 Python 环境,但允许数据科学家使用可用的最新版本进行 ad hoc 数据分析
  • 硬件制造商将稳定的 Python 版本作为其生产固件的一部分进行部署,但在其自动化集成测试的开发和执行中使用可用的最新版本

在任何发布模型下,Python 的每个新发布都会为这些组织带来工作。这些工作可能涉及对 Python 本身的法律、安全或技术审查,评估和验证有影响力的更改,重新应用补丁,重新编译和测试第三方依赖项,然后才能进行部署。

能够快速获得更新的组织应该能够利用更频繁的 beta 版本。虽然每次更新仍然需要与今天相似的调查工作,但每次发布的工​​作量应该会减少,因为每次发布将比当前模型下的发布更相似。拟议的“每 2 个月发布一次”模型的优点之一是,组织可以选择自己的采用周期,从采用每个 beta 版本,到每季度采用一个,或者每 6 个月采用一个,或者每年采用一个。在此之外,继续使用稳定版可能会更有意义。

对于评估更严格或偏好稳定的组织来说,更长的稳定版发布周期将减少更新所需的年度工作量,更长的发布候选期将允许在 X.Y.0 发布之前进行更长的内部测试时间,并且在 beta 期间被其他人更广泛地使用将为初始版本提供更大的信心。同时,组织可以放心地在维护版本之间进行更长时间的升级,而不必担心破坏性更改。

致谢

感谢 Łukasz Langa 创建 PEP 602 并促使讨论 CPython 发布节奏的可能改进,感谢 Kyle Stanley 和 h-vetinari 对本 PEP 初稿的建设性反馈。

参考资料


来源:https://github.com/python/peps/blob/main/peps/pep-0605.rst

最后修改:2025-02-01 08:59:27 GMT