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

Python 增强提案

PEP 408 – 标准库 __preview__ 包

作者:
Alyssa Coghlan <ncoghlan at gmail.com>, Eli Bendersky <eliben at gmail.com>
状态:
已拒绝
类型:
标准跟踪
创建时间:
2012 年 1 月 7 日
Python 版本:
3.3
历史记录:
2012 年 1 月 27 日
决议:
Python-Dev 消息

目录

摘要

将新模块纳入 Python 标准库的过程受到 API 锁定和模块正式成为 Python 一部分所隐含的向后兼容性承诺的阻碍。本 PEP 提出了一种模块的过渡状态 - 在正式纳入标准库之前,在次要版本(大约 18 个月)期间,将其纳入一个特殊的 __preview__ 包中。一方面,这种状态为模块提供了正式成为 Python 发行版一部分的好处。另一方面,核心开发团队明确表示,关于模块最终是否完全纳入标准库,或其 API 的稳定性(可能会在下一次发布中发生变化)不作任何承诺。

PEP 拒绝

基于他在 Google App Engine 中使用类似“labs”命名空间的经验,Guido 拒绝了这个 PEP [3],他倾向于更简单的替代方案,即在文档中明确标记临时模块。

如果一个模块被认为适合纳入标准库,但对可维护性或某些 API 细节仍然存在一些疑虑,则可以以临时方式接受该模块。虽然这被认为是不可能的结果,但如果这些挥之不去的疑虑被证明是合理的,此类模块 *可能会* 从标准库中删除,而不会经过过时阶段。

在同一公告中,Guido 明确接受了 Matthew Barnett 的‘regex’ 模块 [4] 作为 Python 3.3 的标准库的临时添加(使用‘regex’ 名称,而不是作为现有‘re’ 模块的直接替换)。

提案 - __preview__ 包

每当 Python 核心开发团队决定将新模块纳入标准库,但又不太确定模块的 API 是否最佳时,该模块可以放置在一个名为 __preview__ 的特殊包中,持续一个次要版本。

在下一次次要版本中,该模块可能会“毕业”到标准库中(并占据其命名空间中的自然位置,离开 __preview__ 包),也可能被拒绝并从 Python 源代码树中完全删除。如果该模块在 __preview__ 中停留一个次要版本后,最终毕业到标准库,则其 API 可能会根据累积的反馈进行更改。核心开发团队明确不对 __preview__ 中的模块的 API 稳定性和向后兼容性做出任何保证。

进入 __preview__ 包标志着该模块向标准库过渡的开始。这意味着核心开发团队承担了该模块的责任,与标准库中的任何其他模块类似。

哪些模块应该通过 __preview__

我们预计大多数被提议添加到 Python 标准库中的模块都将在 __preview__ 中经过一个次要版本。但是,也可能存在一些例外,例如使用预定义 API 的模块(例如 lzma,它通常遵循现有 bz2 模块的 API),或者 API 在 Python 开发社区中被广泛接受的模块。

无论如何,提议添加到标准库中的模块,无论是通过 __preview__ 还是直接添加,都必须满足 PEP 2 制定的接受条件。

重要的是要强调,本提案的目的是不要使将新模块添加到标准库的过程变得更加困难。相反,它试图提供一种添加 *更多* 有用库的方法。那些明显适合纳入的模块可以像以前一样添加。由于对 API 的不确定性而可能长期停滞的模块现在有一种方法可以通过在 __preview__ 包中进行孵化期来与 Python 一起分发。

“毕业”标准

原则上,__preview__ 包中的大多数模块最终应该毕业到稳定的标准库。没有毕业的一些原因是

  • 该模块可能会被证明是不稳定或脆弱的,没有足够的开发人员支持来维护它。
  • 在预览版本期间可能会找到更好的替代模块。

本质上,核心开发人员将根据具体情况做出决定。这里要强调的是,模块在某个版本中出现在 __preview__ 包中并不能保证它在下个版本中还会是 Python 的一部分。

示例

假设 example 模块是纳入标准库的候选者,但一些 Python 开发人员并不相信它为其试图解决的问题提供了最佳 API。然后该模块可以在 3.X 版本中添加到 __preview__ 包中,可以通过以下方式导入

from __preview__ import example

假设该模块随后在 3.X+1 版本中被提升到标准库中,它将被移到库中的永久位置

import example

__preview__ 中导入它将不再起作用。

基本原理

核心开发团队的益处

目前,核心开发人员非常不愿意向标准库添加新接口。这是因为一旦它们在某个版本中发布,API 设计错误就会由于向后兼容性问题而被锁定。

通过将所有主要 API 添加操作通过某种预览机制进行一个完整的版本控制,我们可以在锁定 API 并提供标准的向后兼容性保证之前,获得一个完整的版本周期的社区反馈。

我们也可以开始将预览模块与标准库的其余部分集成,只要我们向打包人员说明,预览模块不应该被视为可选的。预览 API 与标准库其余部分唯一的区别在于,预览 API 明确地不受通常的向后兼容性保证的约束。

本质上,__preview__ 包旨在降低锁定长期 API 设计错误的风险。目前,这种担忧可能会阻止新的添加,即使核心开发团队的共识是,从原则上讲,某个添加是一个好主意。

最终用户的益处

对于未来的最终用户来说,最大的好处在于更好的“开箱即用”体验 - 而不是被告知“哦,标准库中用于执行 X 任务的工具很糟糕,请下载这个第三方库”,那些更好的工具更有可能只是一个导入的距离。

对于需要对上游依赖项进行尽职调查的环境(严重损害了 PyPI 上大部分材料的成本效益,甚至完全排除了这些材料),主要的好处在于确保 __preview__ 包中的任何内容都清楚地处于 python-dev 的保护之下,至少从以下几个方面来看

  • 许可:由 PSF 根据贡献者许可协议重新分发。
  • 文档:模块的文档通过标准的 Python 文档工具发布和组织(即 ReST 源代码,使用 Sphinx 生成的输出,发布在 https://docs.pythonlang.cn 上)。
  • 测试:模块测试套件在 python.org buildbot 集群上运行,结果通过 https://pythonlang.cn/dev/buildbot 发布。
  • 问题管理:错误和功能请求在 http://bugs.python.org 上处理。
  • 源代码控制:该软件的主仓库发布在 http://hg.python.org 上。

纳入 __preview__ 的候选者

对于 Python 3.3,目前有一些明显的候选者

其他可能的未来用例包括

  • 改进的 HTTP 模块(例如 requests
  • HTML 5 解析支持(例如 html5lib
  • 改进的 URL/URI/IRI 解析
  • 标准图像 API (PEP 368)
  • 导入状态的封装 (PEP 368)
  • 标准事件循环 API (PEP 3153)
  • Python 3 的 WSGI 的二进制版本(例如 PEP 444
  • 泛型函数支持(例如 simplegeneric

与 PEP 407 的关系

PEP 407 提出对核心 Python 发布周期进行更改,以允许每 6 个月发布一次临时版本(可能仅限于标准库更新)。如果对发布周期进行了这样的更改,则建议针对 __preview__ 命名空间的以下策略

  • 对于长期支持版本,__preview__ 命名空间将始终为空。
  • 新模块将仅在紧随长期支持版本之后的临时版本中被接受到 __preview__ 命名空间中。
  • 所有添加的模块将在下一个长期支持版本之前迁移到标准库中的最终位置,或者完全删除。

已拒绝的替代方案和变体

使用 __future__

Python 已经有一个“前瞻性”命名空间,即 __future__ 模块,因此有理由问为什么不能将它重新用于此新目的。

这样做不合适的理由有两个:

1. __future__ 模块实际上与一个单独的编译器指令功能相关联,该功能实际上可以改变 Python 解释器编译模块的方式。我们不希望预览包出现这种情况 - 我们只想要一个普通的 Python 包。

2. __future__ 模块附带了一个明确的承诺,即名称将永久保留,即使相关功能已成为编译器的默认行为很久之后。同样,这与预览包的预期目的完全相反 - 几乎可以肯定的是,所有添加到预览中的名称最终都会被删除,最有可能的原因是它们被移动到标准库中的永久位置,但也可能由于它们被恢复到第三方包状态(如果社区反馈表明建议的添加是不可挽回的错误)。

对包进行版本控制

一个提议的替代方案 [1] 是向 __preview__ 包添加显式版本控制,即 __preview34__。我们认为,简单地定义一个模块在 Python 3.X 中位于 __preview__ 中,要么在 Python 3.X+1 中升级到正常的标准库命名空间,要么从 Python 源代码树中完全消失,这样做更好。对 _preview__ 包进行版本控制会使流程变得复杂,并且与该提议的主要意图不符。

使用没有前导和尾随下划线的包名

有人建议 [1] 使用 previewexp 这样的包名,而不是 __preview__。在讨论中,由于 “dunder” 包名(即,以两个下划线开头和结尾的名称)在 Python 中的特殊含义,因此拒绝了该提议。此外,非“dunder”名称会暗示正常的标准库 API 稳定性保证,而这并非 __preview__ 包的意图。

保留 pickle 兼容性

基于版本 3.X 中 __preview__ 中模块的腌制类实例在版本 3.X+1 中将无法反腌制,因为该模块将不再位于 __preview__ 中。可以添加特殊代码来使之工作,但这与该提议的意图背道而驰,因为它暗示了向后兼容性。因此,本 PEP 并不提议保留腌制兼容性。

致谢

Dj Gilcrease 最初提出了在 Python 中使用 __preview__ 包的想法 [2]。虽然他最初的提议使用 __experimental__ 这个名字,但我们认为 __preview__ 更好地传达了此包的含义。

参考


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

上次修改:2023-10-11 12:05:51 GMT