PEP 387 – 向后兼容性策略
- 作者:
- Benjamin Peterson <benjamin at python.org>
- PEP 代理人:
- Brett Cannon <brett at python.org>
- 状态:
- 活跃
- 类型:
- 流程
- 创建日期:
- 2009年6月18日
- 发布历史:
- 2009年6月19日, 2020年6月12日, 2022年12月19日, 2023年6月16日
- 取代:
- 291
摘要
本PEP概述了Python的向后兼容性策略。
基本原理
作为当今使用最广泛的编程语言之一[1],Python核心语言及其标准库在数百万应用程序和库中发挥着关键作用。这非常棒。然而,这意味着开发团队必须非常小心,以免新版本破坏这些现有的第三方代码。
本PEP认为“向后不兼容性”意味着在更改后,现有代码停止相对正常地运行。我们承认这并非一个具体的定义,但期望人们普遍理解“向后不兼容性”的含义,如果他们不确定,可以向Python开发团队和/或指导委员会寻求指导。
向后兼容性规则
此策略适用于所有公共API。这些包括:
- 参考手册中定义的这些构造的语法和行为。
- C-API。
- 函数、类、模块、属性和方法的名称和类型。
- 给定一组参数时,函数的返回值、副作用和引发的异常。这不排除合理错误修复导致的更改。
- 参数和返回值的位置和预期类型。
- 类在子类方面的行为:何时调用被覆盖的方法的条件。
- 已记录的异常以及导致其引发的语义。
- 在EAFP场景中通常引发的异常。
其他明确不属于公共API的部分。它们可以在任何时间以任何方式更改或删除。这些包括:
- 以“_”为前缀的函数、类、模块、属性、方法和C-API名称和类型(特殊名称除外)。
- 任何公开文档中声明为私有的内容。请注意,如果某项内容完全未被记录,它不会自动被视为私有。
- 导入的模块(除非明确文档化为公共API的一部分;例如,在
spam模块中导入bacon模块并不自动意味着spam.bacon是公共API的一部分,除非它被如此文档化)。 - 内部类的继承模式。
- 测试套件。(
Lib/test目录或包的测试子目录中的任何内容。) - 向后兼容性规则不适用于任何根据PEP 411明确标记为试用版的模块或API。
向后兼容性的基本策略
- 一般来说,不兼容性应具有较大的收益/破坏比,并且不兼容性应易于在受影响的代码中解决。例如,添加一个与第三方包同名的标准库模块通常是不可接受的。然而,通过继承添加一个与第三方代码冲突的方法或属性可能是合理的。
- 除非正在进行下面的弃用过程,否则API的行为在任何两个连续版本之间不得以不兼容的方式更改。Python的年度发布流程(PEP 602)意味着弃用期必须至少持续两年。
- 同样,在任何两个连续版本之间,功能不能在没有通知的情况下被删除。
- 对于无法引发弃用警告的更改,请咨询指导委员会。
- 指导委员会可以批准本政策的例外。特别是,他们可以缩短某项功能的所需弃用期。例外情况仅在极端情况下获得批准,例如危险的损坏或不安全的功能,或没有人会合理依赖的功能(例如,对完全过时平台的支持)。
软弃用
当API不再用于编写新代码,但在现有代码中继续使用仍然安全时,可以使用软弃用。API仍然有文档和测试,但不会进一步开发(不进行增强)。
“软”弃用与(常规的)“硬”弃用之间的主要区别在于,软弃用不意味着安排废弃API的移除。
另一个区别是软弃用不会发出警告:它仅在文档中提及,而通常“硬”弃用会在运行时发出DeprecationWarning警告。软弃用的文档应解释为何应避免使用该API,并尽可能提出替代方案。
如果决定弃用(在常规意义上)目前处于软弃用状态的功能,则弃用必须遵循向后兼容性规则(即,不因为该功能已处于软弃用状态而存在例外)。
进行不兼容的更改
进行不兼容更改是一个逐步的过程,需要通过多个版本完成:
- 讨论更改。根据不兼容的程度,这可能在bug追踪器、python-dev、python-list或适当的SIG上进行。可能会编写PEP或类似文档。希望受影响API的用户能积极发表评论。
- 在当前的
main分支中添加警告。如果行为正在改变,API可能会增加一个新函数或方法来执行新行为;旧用法应引发警告。如果API正在被移除,则只要进入该API就发出警告。DeprecationWarning是常用的警告类别,但在旧版本和新版本API将共存多个版本的特殊情况下,可以使用PendingDeprecationWarning[2]。警告消息应包含预计不兼容性将成为默认值的版本以及用户可以提交反馈问题的链接。如果可行,还应更改typeshed以向已弃用的API添加@deprecated装饰器(参见PEP 702),以便静态类型检查器的用户有另一种方式了解弃用。对于C API,
Py_DEPRECATED宏生成的编译器警告也是可以接受的。 - 等待警告在至少两个相同主版本的次要Python版本中出现,或者在一个较旧主版本的一个次要版本中出现(例如,对于Python 3.10.0中的警告,你需要等到至少Python 3.12或Python 4.0才能进行更改)。然而,最好等待5年再移除(例如,从Python 3.10开始警告,在3.15中移除;这恰好与Python当前次要版本的生命周期一致)。
- 如果弃用行为的预期维护开销和安全风险很小(例如,一个旧函数以一个新的、更通用的函数重新实现),它可以无限期保留(或者直到情况改变)。
- 如果已弃用的功能被新功能取代,通常应在不包含新功能的最后一个 Python 版本停止支持后才能移除。
- 看看是否有任何反馈。未参与最初讨论的用户在看到警告后可能会发表评论。也许可以重新考虑。
- 行为更改或功能移除现在可以在达到声明的版本后成为默认或永久更改。移除旧版本和警告。
- 如果无法向用户提供警告,请咨询指导委员会。
更新日志
- 2025年1月27日:更新为优先采用5年弃用期再移除。
- 2023年11月14日:根据PEP 702添加了
@deprecated装饰器。 - 2023年7月3日:添加了软弃用部分,如https://discuss.python.org/t/27957中所讨论。
- 2023年6月26日:多项小更新和澄清,如https://discuss.python.org/t/22042中所讨论。
- 2022年4月4日:在几个特殊情况下明确指出应咨询指导委员会。
- 2021年4月16日:澄清了在进行更改之前必须发出警告的时长。
- 2020年7月20日:初始接受版本。
参考资料
版权
本文档已置于公共领域。
来源: https://github.com/python/peps/blob/main/peps/pep-0387.rst
最后修改: 2025-09-10 02:08:01 GMT