PEP 2026 – Python 的日历版本
- 作者:
- Hugo van Kemenade
- 讨论地址:
- Discourse 主题
- 状态:
- 草稿
- 类型:
- 流程
- 创建日期:
- 2024-06-11
- Python 版本:
- 3.26
- 更新历史:
- 2024-06-14
摘要
本 PEP 提出更新 Python 的版本控制方案,以包含日历年份。
日历版本 (CalVer) 使得 _所有_ 内容更容易转换为日历时间,而不是计算版本并查找它们何时将要 (或曾经) 发布。
- 支持生命周期是清晰的,使得很容易看到某个版本首次发布的时间。
- 废弃功能对于维护人员和用户来说更容易管理。
- 更容易确定某个版本何时将达到生命周期结束 (EOL)。
- 这有助于人们 (尤其是新手学习者) 了解他们的安装版本有多旧。
- 更容易确定要为库和应用程序支持哪些 Python 版本。
从原本应该是 Python 3.15 开始,版本号将变为 3.YY.micro,其中 YY 是首次发布的年份
- Python 3.26 将于 2026 年发布,而不是 Python 3.15。EOL 为首次发布后五年,因此 Python 3.26 将于 2031 年达到 EOL。
- Python 3.27 将于 2027 年发布,依此类推。
动机和理由
2019 年,我们通过 PEP 602 采用了年度发布周期,这为日历版本铺平了道路。
采用年度发布日历可以自然地切换到日历版本,例如,将 Python 3.9 称为“Python 3.20”,因为它是在 20 年 10 月发布的,依此类推 (“Python 3.23” 将是在 23 年 10 月发布的)。虽然切换到日历版本的容易程度可以被视为年度发布周期的优势,但本 PEP 并不主张或反对更改 Python 的版本控制方式。如果采用了年度发布周期,版本控制问题将在单独的 PEP 中处理。
这就是那个 PEP。
当前方案
摘自 Python 通用常见问题解答:Python 的版本编号方案是如何运作的?
Python 版本号为“A.B.C”或“A.B”。
- A 是主版本号 - 仅在语言发生重大变化时才增加。
- B 是次版本号 - 针对不太重大的更改进行增加。
- C 是微版本号 - 针对每个错误修复版本进行增加。
Python 早于 SemVer
语义版本控制 (SemVer) 是一种流行的方案,旨在传达版本的意图 (尽管它 并不总是成功)。
给定一个版本号 MAJOR.MINOR.PATCH,在以下情况下增加相应的值:
- 当您进行不兼容的 API 更改时,增加 MAJOR 版本。
- 当您以向后兼容的方式添加功能时,增加 MINOR 版本。
- 当您进行向后兼容的错误修复时,增加 PATCH 版本。
人们经常假设 Python 遵循 SemVer 并 抱怨 关于 破坏性 更改 在 功能 版本 中。但是,Python 比 SemVer 早了至少 15 年:SemVer 规范于 2009 年引入,而 Python 的定制方案则是在 1994 年添加到源代码控制 中,用于 1.0 版本。
如果 Python 采用了 SemVer,这意味着每年删除废弃功能时都会出现新的主版本升级。
然而,除了 SemVer 之外,一些项目采用了另一种基于日历的版本控制方案。
日历版本
使用 日历版本控制 (CalVer),您会在版本号中包含日期的某些元素。 例如,Ubuntu 和 Black 使用年份和月份 - Ubuntu 24.04 于 2024 年 4 月发布;pip 和 PyCharm 仅使用年份。
Ubuntu | Black | pip | PyCharm |
---|---|---|---|
YY.0M.micro | YY.MM.micro | YY.minor.micro | YYYY.minor.micro |
23.04
23.10
24.04
24.10
|
23.12.1
24.1.0
24.1.1
24.2.0
|
23.3
23.3.1
23.3.2
24.0
|
2023.3.5
2024.1
2024.1.1
2024.1.2
|
以下是一些编程语言标准,它们都使用了某种形式的年份
Ada | Algol | C | C++ | Fortran | ECMAScript
又名 JavaScript
|
---|---|---|---|---|---|
YY / YYYY | YY | YY | YY | YY / YYYY | YYYY |
83
95
2012
2022
|
58
60
68
|
89
99
11
23
|
98
03
11
23
|
66
90
2003
2023
|
2020
2021
2022
2023
|
年度发布节奏
自 2019 年以来,我们每年都会发布一个版本。
- 3.15.0 将于 2026 年发布
- 3.16.0 将于 2027 年发布
- 3.17.0 将于 2028 年发布
- 3.18.0 将于 2029 年发布
- 3.19.0 将于 2030 年发布
这有点像基于日历的,只是它被偏移了 11 年。
Python 的 CalVer
最简单的 CalVer 选项是坚持使用主版本 3,并在次版本中编码年份。
- 3.26.0 将于 2026 年发布
- 3.27.0 将于 2027 年发布
- 3.28.0 将于 2028 年发布
- 3.29.0 将于 2029 年发布
- 3.30.0 将于 2030 年发布
例如,3.26 将于 2026 年发布。它使发布的首次发布时间变得一目了然。
明确废弃功能的移除
废弃功能的警告通常会提到它们将在哪个版本中被移除。例如
DeprecationWarning: ‘ctypes.SetPointerType’ 已被弃用,并计划在 Python 3.15 中移除
然而,一旦了解了 CalVer,您就可以从警告中立即清楚地知道您需要采取行动的时间
DeprecationWarning: ‘ctypes.SetPointerType’ 已被弃用,并计划在 Python 3.26 中移除
明确支持周期
现在,确定一个版本何时到达生命周期结束有点麻烦。首先您需要查找它最初发布的时间,然后加上 5 年。
“Python 3.11 什么时候会到 EOL?”“嗯,让我们看看… PEP 664 是 3.11 发布计划,它说 3.11 于 2022 年发布,EOL 为发布后 5 年,所以 2022 + 5 = 2027。”
但是,如果首次发布年份就在版本号中,那么会容易得多
“Python 3.26 什么时候会到 EOL?”“26 + 5 = [20]31”
明确安装版本时间
有了版本号中的年份,更容易确定您的安装版本有多旧。例如,在当前方案中,如果您在 2035 年使用的是 Python 3.15,则不清楚它是在 2026 年首次发布的 (并且自 2031 年以来一直处于 EOL 状态)。
如果您了解 CalVer,那么如果您在 2035 年使用的是 Python 3.26,很明显它是在九年前首次发布的,现在可能是时候升级了。
这可以帮助人们切换到仍处于安全支持下的受支持版本,并有助于教授可能使用旧安装版本的新用户。
明确版本支持
CalVer 使得更容易确定要支持哪些 Python 版本。
例如,如果没有 CalVer,将您的最低兼容 Python 版本设置为 2031 年的 3.19,这会对版本采用和支持做出过于乐观的假设。
然而,有了 CalVer,将最低版本设置为 2031 年的 3.30 就更加清晰。为了更广泛的支持,您可能更喜欢将其设置为 3.26。
同样,支持所有 CPython 上游版本的库维护人员需要针对五个版本进行测试 (或者包括预发布版本在内,则为六个版本)。
例如,在 2030 年,没有 CalVer 的受支持版本将是
- 3.15, 3.16, 3.17, 3.18, 3.19
有了 CalVer,它们将是
- 3.26, 3.27, 3.28, 3.29, 3.30
维护人员可以一目了然地看到哪些版本是当前版本,需要进行测试。
非目标
与当前方案类似,仅针对错误修复和安全发布增加微版本,主版本和次版本保持不变。例如
当前方案 | 建议的 3.YY.micro | |
---|---|---|
首次发布 (26 年 10 月) | 3.15.0 | 3.26.0 |
第一个错误修复版本 (26 年 12 月) | 3.15.1 | 3.26.1 |
第二个错误修复版本 (27 年 2 月) | 3.15.2 | 3.26.2 |
… | … | … |
最终安全版本 (31 年 10 月) | 3.15.17 | 3.26.17 |
对 PEP 602 (Python 年度发布周期) 没有任何改变。
- 对开发功能版本 (alpha 版、beta 版和发布候选版) 的 17 个月没有改变。
- 对支持时间没有改变:两年完整支持和三年安全修复。
- 对每年的 10 月发布节奏没有改变。
规范
Python 版本号为 3.YY.micro,其中
- 3 是主版本号 - 它始终为 3。
- YY 是次版本号 - 它代表短年份号:
{year} - 2000
。 - micro 是微版本号 - 它针对每个错误修复或安全版本进行增加。
我们将保留主版本 3。Python 3 是品牌;不会有 Python 4。
在 2100 年,次版本号将为 2100-2000 = 100
,因此版本号将为 3.100.0。
Python 3.14 将是此次更改前的最后一个版本,它将于 2025 年发布。Python 3.26 将是此次更改后的第一个版本,它将于 2026 年发布。将不会有 Python 3.15 到 3.25 (含)。
安全影响
目前未知。对错误修复和安全阶段的持续时间或时间安排没有改变。
如何教授
我们将在博客、3.14 版本说明、文档中以及通过与社区的互动宣布此事。
此次更改的目标是 3.14 之后的版本:它将不再是 3.15,而是 3.26。本 PEP 于 2024 年 6 月提出。3.15/3.26 版本的开发将于 2025 年 5 月开始,第一个 alpha 版将于 2025 年 10 月发布,第一个版本将于 2026 年 10 月发布。我们可以在 3.14 周期内更新文档。这提供了充足的通知时间。
我们可以制作仅更改版本的预览构建,用于早期测试。
我们可以将 python3.15
命令作为 Python 3.26 的一部分进行发布,该命令会立即报错并提示用户改用 python3.26
。
被拒绝的想法
YY.0
例如,Python 26.0 将于 2026 年发布。
对 Python 4 版本 没有多少兴趣。 我们不想重蹈 2 到 3 的覆辙,并且 4 到现在已经有了很多期望。我们不想进行“重大的更改”。
也许 Python 4 可以为一些重大事件预留,比如移除 GIL(PEP 703),但指导委员会明确表示,免费线程的推出必须循序渐进。我们是否会永远使用 版本 3?
另一种选择是在主版本中加入年份,跳到 26.0。这意味着我们可以跳过所有 4.0 的包袱。
生态系统变化
将主版本更改为两位数会破坏代码吗?
是的,任何对版本的新更改都会不可避免地这样做,因为人们会做出一些假设,例如主版本总是 3,或者版本部分总是单个数字。例如
版本更改 | 示例 | 预期 | 实际 |
---|---|---|---|
2.7.9 → 2.7.10 | 'this is Python {}'.format(sys.version[:5])
|
2.7.10 | 2.7.1 |
3.9 → 3.10 | ".%s-%s" % (get_platform(), sys.version[0:3])
|
3.10 | 3.1 |
3 → 4 | if sys.version_info[1] >= 9:
|
4.0 | 0 |
3 → 26 | if sys.version[0] == '3':
|
26 | 2 |
最后一个与 YY.0 版本控制最相关。因此,3.YY 方案是最安全的,并且需要最少的更改,因为版本的形状没有改变:它仍然是 3 后面跟着两位数字。
提示
使用 Ruff 的 YTT 规则 或 Flake8 的 flake8-2020 插件 来帮助找到这些问题。
python3
命令
PEP 394(Unix 类系统上的“python”命令)概述了对 python
、python2
和 python3
命令的建议。 python
可以映射到 python2
或 python3
。如果主版本更改并且每年开始更改,则需要重新审视这些问题。
在 Python 2.7 结束生命周期四年后,我们可以建议 python
仅映射到最新的 Python 3+ 版本。但是,当 Python 26.0 发布时,python3
会映射到哪里?这会带来额外的复杂性和成本。
CPython 更改
除了 python3
命令更改外,CPython 中至少有四个地方假设主版本是 3,需要更新
YY.0 拒绝
与 YY.0 版本控制的综合成本相比,日历版本控制的好处并不大。因此,拒绝 YY.0 版本控制。
YY.MM
例如,Python 26.10 将于 2026 年 10 月发布。
基于 YY.0 版本控制,我们还可以将发布月份作为次版本,就像 Ubuntu 和 Black 一样。这将明确表明它是在哪一年发布的,以及它将在哪一年结束生命周期。
然而,YY.MM 版本控制因与 YY.0 版本控制相同的许多原因而被拒绝。
3.YYYY
例如,Python 3.2026 将于 2026 年发布。
使用四位数字更清楚地表明次版本是年份,并且避免与使用 YY.MM 的 Ubuntu 版本混淆。但是,这被拒绝,因为从两位数更改为四位数会比 3.YY 版本控制破坏更多代码。
版本
例如,Python 3.15(2026 版)将于 2026 年发布。
Rust 语言使用 “版本” 来引入重大更改。将此应用于 Python 将需要对 PEP 387(向后兼容性策略)进行重大更改,并且超出了此 PEP 的范围。
我们可以将年份标签应用于发行版,例如“Python 3.15(2026 版)”,但这是被拒绝的,因为我们必须跟踪两个数字。
采用 SemVer 并跳过 4
例如,Python 5.0 将于 2026 年发布,6.0 将于 2027 年发布,等等。
我们可以完全跳过有问题的 4.0 并采用 SemVer。由于弃用在每次功能发布中都会被移除,因此我们每年都会得到一个新的主版本提升。
这是被拒绝的,因为我们不会获得日历版本控制的好处,并且从 3.x 转移也会 破坏代码。
在 3.14 周期中更改
Python 3.14 版本必须发布,因为:π。
向后兼容性
这种版本更改是考虑到的 CalVer 选项中最安全的(参见 被拒绝的想法):我们将 3 保留为主版本,次版本仍然是两位数。次版本最终将变为三位数,但这是可以预测的,并且距离很远,可以提前规划。
我们保留 python3
可执行文件。
版本映射
版本 3.15 到 3.25(含)将被跳过。为这些版本计划的功能、弃用和移除将重新映射到新的版本号。
例如,最初计划在 3.16 中移除的弃用将改为在 3.27 中移除。
旧版本 | 新版本 | 初始发布 |
---|---|---|
3.14 | 3.14(无变化) | 2025 |
3.15 | 3.26 | 2026 |
3.16 | 3.27 | 2027 |
3.17 | 3.28 | 2028 |
3.18 | 3.29 | 2029 |
3.19 | 3.30 | 2030 |
3.20 | 3.31 | 2031 |
3.21 | 3.32 | 2032 |
3.22 | 3.33 | 2033 |
3.23 | 3.34 | 2034 |
3.24 | 3.35 | 2035 |
3.25 | 3.36 | 2036 |
向前兼容性
未来节奏变化
此 PEP 针对 PEP 602 中定义的年度发布节奏,没有提出任何更改,该 PEP 概述了 年度发布的许多充分理由(例如,具有可预测发布日历的较小发布,以及与外部重新分发者的同步)。然而,即使不太可能,如果我们将来决定更改节奏,CalVer 也不会阻止这样做。
频率降低
如果我们一年发布少于一次,建议的 CalVer 方案仍然有效;实际上,它甚至可以帮助人们知道在哪个年份可以预期发布。例如,如果我们从 2036 年开始每隔一年发布一次
- 3.36.0 将于 2036 年发布
- 3.38.0 将于 2038 年发布
- 等等
生态系统更改部分取决于假设的更改节奏 PEP 如何更新 PEP 387(向后兼容性策略)。例如,如果它要求弃用期必须至少为一次功能发布,而不是当前的两次(以保持最少两年),那么 CalVer 在不需要对计划的移除版本进行任何更改(除了调整任何落在非发布年份的版本)方面,比现状更有优势。
频率提高
如果我们一年发布多次,这里有一些选择。例如,如果我们从 2036 年开始在 4 月和 10 月发布,接下来的四次发布可能是
方案 | 备注 | 2036 a | 2036 b | 2037 a | 2037 b |
---|---|---|---|---|---|
YY.MM.micro | 年份作为主版本,月份作为次版本 | 36.04.0 | 36.10.0 | 37.04.0 | 37.10.0 |
YY.x.微版本 | 年份作为主版本,序列号作为次版本 | 36.1.0 | 36.2.0 | 37.1.0 | 37.2.0 |
3.YYMM.微版本 | 将年份和月份组合作为次版本 | 3.3604.0 | 3.3610.0 | 3.3704.0 | 3.3710.0 |
3.YYx.微版本 | 将年份和序列号组合作为次版本 | 3.360.0 | 3.361.0 | 3.370.0 | 3.371.0 |
3.YY.MM.微版本 | 添加额外的月份段 | 3.36.04.0 | 3.36.10.0 | 3.37.04.0 | 3.37.10.0 |
3.主版本.微版本 | 不再使用 CalVer:增加次版本 | 3.36.0 | 3.37.0 | 3.38.0 | 3.39.0 |
3.50.0 | 3.51.0 | 3.52.0 | 3.53.0 | ||
3.100.0 | 3.101.0 | 3.102.0 | 3.103.0 | ||
4.主版本.微版本 | 不再使用 CalVer:增加主版本 | 4.0.0 | 4.1.0 | 4.2.0 | 4.3.0 |
5.主版本.微版本 | 5.0.0 | 5.1.0 | 5.2.0 | 5.3.0 |
YY 选项需要解决围绕 平台兼容性标签、python3 命令 以及 假设版本总是以 3 开头 的代码问题。
保留主版本 3 但将次版本更改为三位数或四位数的选项还需要解决 假设版本总是两位数 的代码问题。
添加额外的月份段的选项是最大的变化,因为代码需要处理四部分版本而不是三部分版本。
放弃 CalVer 的选项将是最保守的,允许自由选择主版本和次版本。
不再使用 CalVer
现在采用 CalVer 并不排除将来放弃 CalVer,例如,回到原始方案、SemVer 或其他方案。一些选项 列在上面的表格中。如果想要明确表明次版本不再是年份,可以将其提升到更高的整数(例如,3.50 或 3.100),或者可以提升主版本(例如,提升到 4.0 或 5.0)。此外,可以考虑 版本纪元。
脚注
作者在 2024 年 Python 语言峰会 上提出了日历版本控制;此 PEP 是在峰会上以及在 PyCon US 期间讨论的结果。
致谢
感谢 Seth Michael Larson 提供的语言峰会问答笔记和博客文章,感谢所有在峰会和 PyCon US 上提供反馈的人。
感谢 Łukasz Langa 和 Alex Waygood 审阅此 PEP 草案。
版权
本文件置于公有领域或 CC0-1.0-Universal 许可下,以更具许可性的方式使用。
来源:https://github.com/python/peps/blob/main/peps/pep-2026.rst
上次修改时间:2024-09-12 17:30:18 GMT