NEP 29 — 建议 Python 和 NumPy 版本支持作为社区政策标准#

作者:

Thomas A Caswell <tcaswell@gmail.com>, Andreas Mueller, Brian Granger, Madicken Munk, Ralf Gommers, Matt Haberland <mhaberla@calpoly.edu>, Matthias Bussonnier <bussonniermatthias@gmail.com>, Stefan van der Walt <stefanv@berkeley.edu>

状态:

最终

类型:

信息

创建:

2019-07-13

决议:

https://mail.python.org/pipermail/numpy-discussion/2019-October/080128.html

注意

此 NEP 被科学 Python 生态系统协调指南 SPEC 0 — 最低支持版本 取代。

摘要#

此 NEP 建议科学 Python 生态系统中的所有项目采用共同的“基于时间窗口”策略来支持 Python 和 NumPy 版本。标准化对项目支持最低 Python 和 NumPy 版本的建议将改善下游项目规划。

这是一个不同寻常的 NEP,因为它为社区范围的政策提供建议,而不是针对 NumPy 本身的更改。由于没有 SPEEP(科学 Python 生态系统增强提案)的共同场所,并且鉴于 NumPy 在生态系统中的核心作用,NEP 提供了一个可见的地方来记录建议的策略。

此 NEP 由 Matplotlib、scikit-learn、IPython、Jupyter、yt、SciPy、NumPy 和 scikit-image 的维护者提出。

详细说明#

为了本 NEP 的目的,我们假设语义版本控制并定义

主版本

更改第一个数字的版本(例如 X.0.0)

次版本

更改第二个数字的版本(例如 1.Y.0)

补丁版本

更改第三个数字的版本(例如 1.1.Z)

当项目发布新的主版本或次版本时,我们建议他们至少支持在过去的 42 个月(从预期发布日期算起)中引入和发布的所有 Python 次版本,至少支持 2 个 Python 次版本,以及在过去的 24 个月(从预期发布日期算起)中发布的所有 NumPy 次版本,至少支持 3 个 NumPy 次版本。

考虑以下时间线

     Jan 16      Jan 17      Jan 18      Jan 19      Jan 20
     |           |           |           |           |
+++++|+++++++++++|+++++++++++|+++++++++++|+++++++++++|++++++++++++
 |              |                  |               |
 py 3.5.0       py 3.6.0           py 3.7.0        py 3.8.0
|-----------------------------------------> Feb19
          |-----------------------------------------> Dec19
                    |-----------------------------------------> Nov20

它显示了 Python 的 42 个月支持窗口。在 2019 年 2 月发布主版本或次版本的项目应支持 Python 3.5 及更高版本,在 2019 年 12 月发布主版本或次版本的项目应支持 Python 3.6 及更高版本,在 2020 年 11 月发布主版本或次版本的项目应支持 Python 3.7 及更高版本。

在起草本 NEP 时,Python 发布节奏为 18 个月,因此 42 个月窗口确保窗口中始终至少有两个 Python 次版本。该窗口比预期的 Python 两个发布间隔延长了 6 个月,以提供对 Python 发布计划中微小波动/延迟的弹性。

Python 发布节奏在 PEP 0602 中有所提高,现在每年发布一次,因此支持窗口中将始终有 3-4 个 Python 版本。但是,PEP 0602 不会缩短 Python 的支持窗口(18 个月的定期完整错误修复版本和 42 个月的按需源代码版本)。因此,我们不希望我们的用户更快地升级 Python,我们的 42 个月支持窗口将涵盖任何给定 Python 版本的上游支持的相同部分。

由于 Python 次版本支持仅基于历史发布日期、42 个月时间窗口和计划的项目发布日期,因此可以高置信度地预测项目何时可以放弃任何给定的 Python 次版本。这反过来可以节省数月的无谓维护负担。

如果项目在 Python 次版本从支持窗口中删除后立即发布,则不可避免地会存在某些支持版本不匹配的情况,但这种情况应仅持续到生态系统中的其他项目发布为止。

否则,一旦项目执行次版本或主版本发布,就可以保证所有其他项目的稳定版本将从源代码级别支持新版本支持的相同 Python 版本集。

如果有 Python 4 或 NumPy 2,则必须根据社区和项目的最佳利益来审查此策略。

支持表#

日期

Python

NumPy

2020 年 1 月 7 日

3.6+

1.15+

2020 年 6 月 23 日

3.7+

1.15+

2020 年 7 月 23 日

3.7+

1.16+

2021 年 1 月 13 日

3.7+

1.17+

2021 年 7 月 26 日

3.7+

1.18+

2021 年 12 月 22 日

3.7+

1.19+

2021 年 12 月 26 日

3.8+

1.19+

2022 年 6 月 21 日

3.8+

1.20+

2023 年 1 月 31 日

3.8+

1.21+

2023 年 4 月 14 日

3.9+

1.21+

2023 年 6 月 23 日

3.9+

1.22+

2024 年 1 月 1 日

3.9+

1.23+

2024 年 4 月 5 日

3.10+

1.23+

2024 年 6 月 22 日

3.10+

1.24+

2024 年 12 月 18 日

3.10+

1.25+

2025 年 4 月 4 日

3.11+

1.25+

2026 年 4 月 24 日

3.12+

1.25+

删除时间表#

On next release, drop support for Python 3.5 (initially released on Sep 13, 2015)
On Jan 07, 2020 drop support for NumPy 1.14 (initially released on Jan 06, 2018)
On Jun 23, 2020 drop support for Python 3.6 (initially released on Dec 23, 2016)
On Jul 23, 2020 drop support for NumPy 1.15 (initially released on Jul 23, 2018)
On Jan 13, 2021 drop support for NumPy 1.16 (initially released on Jan 13, 2019)
On Jul 26, 2021 drop support for NumPy 1.17 (initially released on Jul 26, 2019)
On Dec 22, 2021 drop support for NumPy 1.18 (initially released on Dec 22, 2019)
On Dec 26, 2021 drop support for Python 3.7 (initially released on Jun 27, 2018)
On Jun 21, 2022 drop support for NumPy 1.19 (initially released on Jun 20, 2020)
On Jan 31, 2023 drop support for NumPy 1.20 (initially released on Jan 31, 2021)
On Apr 14, 2023 drop support for Python 3.8 (initially released on Oct 14, 2019)
On Jun 23, 2023 drop support for NumPy 1.21 (initially released on Jun 22, 2021)
On Jan 01, 2024 drop support for NumPy 1.22 (initially released on Dec 31, 2021)
On Apr 05, 2024 drop support for Python 3.9 (initially released on Oct 05, 2020)
On Jun 22, 2024 drop support for NumPy 1.23 (initially released on Jun 22, 2022)
On Dec 18, 2024 drop support for NumPy 1.24 (initially released on Dec 18, 2022)
On Apr 04, 2025 drop support for Python 3.10 (initially released on Oct 04, 2021)
On Apr 24, 2026 drop support for Python 3.11 (initially released on Oct 24, 2022)

实施#

我们建议所有项目将其开发指南中采用以下语言

本项目支持

  • 项目发布之前 42 个月内发布的所有 Python 次版本,至少支持最新的两个次版本。

  • 项目发布之前 24 个月内发布的所有 numpy 次版本,至少支持最新的三个次版本。

setup.py 中,python_requires 变量应设置为支持的最低 Python 版本。所有支持的 Python 次版本都应在测试矩阵中,并为发布构建二进制工件。

最低 Python 和 NumPy 版本支持应在每次主版本和次版本发布时向上调整,但在补丁版本发布时绝不调整。

向后兼容性#

没有向后兼容性问题。

替代方案#

临时版本支持#

项目可以在每次发布时评估是否增加支持的最低 Python 版本。作为主要缺点,临时方法使下游用户难以预测未来最低版本将是什么。由于没有客观门槛来决定何时应该删除最低版本,因此这些版本支持讨论很容易演变成 自行车棚效应 和尖酸刻薄。

所有 CPython 支持的版本#

CPython 支持的 Python 版本列在 Python 开发人员指南和 Python PEP 中。支持它们是一个非常清晰且保守的方法。但是,这意味着从新功能引入到语言中到项目能够使用它之间存在四年的滞后。此外,对于具有编译扩展的项目,这需要为每个版本构建许多二进制工件。

对于 NumPy 的情况,许多项目都针对后续版本的 NumPy 中修复的错误进行了变通处理。积极主动地提高 NumPy 的最低版本允许下游包携带更少的版本特定补丁。

Linux 发行版上的默认版本#

该策略可能是支持最新 Ubuntu LTS 或 CentOS/RHEL 版本中默认提供的 Python 版本。但是,我们仍然必须在社区范围内标准化要遵循的哪种发行版。

通过遵循主要 Linux 发行版支持的版本,我们放弃了对项目的技术控制权,将其交给可能具有不同动机和关注点的外部组织。

N 个 Python 次版本#

鉴于 Python 当前的发布节奏,建议的时间(42 个月)大致相当于“最新的两个”Python 次版本。但是,如果 Python 大幅更改其发布节奏,任何仅基于发布数量的规则都可能需要更改才能保持合理。

基于 Python 发布数量的策略的一个更基本的问题是,很难预测何时会放弃对特定 Python 次版本的支持,因为这需要正确预测 Python 未来 3-4 年的发布计划。相比之下,基于时间的规则只依赖于过去事件和支持窗口的长度。

从 X.Y.1 Python 版本开始的时间窗口#

这相当于从 X.Y.0 版本开始的几个月的更长支持窗口。这是因为 X.Y.1 错误修复版本通常比 X.Y.0 版本晚几个月,因此从 X.Y.1 开始的 N 个月窗口大约相当于从 X.Y.0 开始的 N+3 个月。

X.Y.0 版本自然是一个特殊的版本。如果我们要将窗口固定在 X.Y.1 上,那么我们将讨论为什么不选择 X.Y.M?

讨论#

参考文献和脚注#

用于生成支持和删除时间表表的代码

from datetime import datetime, timedelta

data = """Jan 15, 2017: NumPy 1.12
Sep 13, 2015: Python 3.5
Dec 23, 2016: Python 3.6
Jun 27, 2018: Python 3.7
Jun 07, 2017: NumPy 1.13
Jan 06, 2018: NumPy 1.14
Jul 23, 2018: NumPy 1.15
Jan 13, 2019: NumPy 1.16
Jul 26, 2019: NumPy 1.17
Oct 14, 2019: Python 3.8
Dec 22, 2019: NumPy 1.18
Jun 20, 2020: NumPy 1.19
Oct 05, 2020: Python 3.9
Jan 30, 2021: NumPy 1.20
Jun 22, 2021: NumPy 1.21
Oct 04, 2021: Python 3.10
Dec 31, 2021: NumPy 1.22
Jun 22, 2022: NumPy 1.23
Oct 24, 2022: Python 3.11
Dec 18, 2022: NumPy 1.24
"""

releases = []

plus42 = timedelta(days=int(365*3.5 + 1))
plus24 = timedelta(days=int(365*2 + 1))

for line in data.splitlines():
    date, project_version = line.split(':')
    project, version = project_version.strip().split(' ')
    release = datetime.strptime(date, '%b %d, %Y')
    if project.lower() == 'numpy':
        drop = release + plus24
    else:
        drop = release + plus42
    releases.append((drop, project, version, release))

releases = sorted(releases, key=lambda x: x[0])


py_major,py_minor = sorted([int(x) for x in r[2].split('.')] for r in releases if r[1] == 'Python')[-1]
minpy = f"{py_major}.{py_minor+1}+"

num_major,num_minor = sorted([int(x) for x in r[2].split('.')] for r in releases if r[1] == 'NumPy')[-1]
minnum = f"{num_major}.{num_minor+1}+"

toprint_drop_dates = ['']
toprint_support_table = []
for d, p, v, r in releases[::-1]:
    df = d.strftime('%b %d, %Y')
    toprint_drop_dates.append(
        f'On {df} drop support for {p} {v} '
        f'(initially released on {r.strftime("%b %d, %Y")})')
    toprint_support_table.append(f'{df} {minpy:<6} {minnum:<5}')
    if p.lower() == 'numpy':
        minnum = v+'+'
    else:
        minpy = v+'+'
print("On next release, drop support for Python 3.5 (initially released on Sep 13, 2015)")
for e in toprint_drop_dates[-4::-1]:
    print(e)

print('============ ====== =====')
print('Date         Python NumPy')
print('------------ ------ -----')
for e in toprint_support_table[-4::-1]:
    print(e)
print('============ ====== =====')