C API 稳定性 — Python 文档
C API 稳定性
Python 的 C API 包含在向后兼容政策 PEP 387 中。 虽然 C API 会随着每个次要版本(例如 从 3.9 到 3.10),大多数更改将与源代码兼容,通常只需添加新的 API。 更改现有 API 或删除 API 仅在弃用期或修复严重问题后进行。
CPython 的应用程序二进制接口 (ABI) 在次要版本中向前和向后兼容(如果它们以相同的方式编译;请参阅下面的 平台注意事项 )。 因此,为 Python 3.10.0 编译的代码将在 3.10.8 上运行,反之亦然,但需要为 3.9.x 和 3.10.x 单独编译。
以下划线为前缀的名称,例如 _Py_InternalState
,是私有 API,即使在补丁版本中也可以在不通知的情况下更改。
稳定的应用程序二进制接口
Python 3.2 引入了 Limited API,它是 Python 的 C API 的一个子集。 仅使用 Limited API 的扩展可以编译一次并与多个 Python 版本一起使用。 受限 API 的内容在 下面列出 。
为了实现这一点,Python 提供了 稳定 ABI:一组将在 Python 3.x 版本之间保持兼容的符号。 稳定 ABI 包含在 Limited API 中公开的符号,但也包含其他符号 - 例如,支持旧版本 Limited API 所需的函数。
(为简单起见,本文档讨论了 扩展 ,但有限 API 和稳定 ABI 的工作方式相同,适用于 API 的所有用途——例如,嵌入 Python。)
- Py_LIMITED_API
在包含
Python.h
之前定义此宏以选择仅使用受限 API,并选择受限 API 版本。将
Py_LIMITED_API
定义为与您的扩展支持的最低 Python 版本对应的 PY_VERSION_HEX 的值。 该扩展无需重新编译从指定版本开始的所有 Python 3 版本,并且可以使用该版本之前引入的有限 API。与其直接使用
PY_VERSION_HEX
宏,不如硬编码一个最小的次要版本(例如0x030A0000
for Python 3.10) 以便在使用未来的 Python 版本编译时保持稳定性。您还可以定义
Py_LIMITED_API
到3
。 这与0x03020000
(Python 3.2,引入有限 API 的版本)相同。
在 Windows 上,使用稳定 ABI 的扩展应该链接到 python3.dll
而不是特定于版本的库,例如 python39.dll
。
在某些平台上,Python 会查找并加载以 abi3
标签命名的共享库文件(例如 mymodule.abi3.so
)。 它不会检查此类扩展是否符合稳定 ABI。 例如,用户(或他们的打包工具)需要确保不会为较低版本的 Python 安装使用 3.10+ Limited API 构建的扩展。
Stable ABI 中的所有函数都作为 Python 共享库中的函数出现,而不仅仅是作为宏。 这使得它们可以从不使用 C 预处理器的语言中使用。
有限的 API 范围和性能
Limited API 的目标是允许使用完整的 C API 实现一切可能,但可能会降低性能。
例如,虽然 PyList_GetItem() 可用,但它的“不安全”宏变体 PyList_GET_ITEM() 不可用。 宏可以更快,因为它可以依赖于列表对象的特定于版本的实现细节。
如果没有定义 Py_LIMITED_API
,一些 C API 函数被内联或被宏替换。 定义 Py_LIMITED_API
禁用此内联,在改进 Python 数据结构时允许稳定性,但可能会降低性能。
通过省略 Py_LIMITED_API
定义,可以使用特定于版本的 ABI 编译受限 API 扩展。 这可以提高该 Python 版本的性能,但会限制兼容性。 使用 Py_LIMITED_API
进行编译将产生一个扩展,该扩展可以在特定版本不可用的情况下进行分发——例如,用于即将发布的 Python 版本的预发布。
有限的 API 警告
请注意,使用 Py_LIMITED_API
进行编译是 不是 代码符合受限 API 或稳定 ABI 的完整保证。 Py_LIMITED_API
仅涵盖定义,但 API 还包括其他问题,例如预期语义。
Py_LIMITED_API
没有防范的一个问题是调用带有在较低 Python 版本中无效的参数的函数。 例如,考虑一个开始接受 NULL
作为参数的函数。 在 Python 3.9 中,NULL
现在选择默认行为,但在 Python 3.8 中,将直接使用该参数,导致 NULL
取消引用和崩溃。 类似的论点适用于结构域。
另一个问题是,当定义 Py_LIMITED_API
时,某些结构体字段当前并未隐藏,即使它们是 Limited API 的一部分。
出于这些原因,我们建议使用它支持的 all 次要 Python 版本测试扩展,并且最好使用 lowest 此类版本进行构建。
我们还建议查看所有使用过的 API 的文档,以检查它是否明确属于受限 API。 即使定义了 Py_LIMITED_API
,也会由于技术原因(甚至无意中作为错误)暴露一些私有声明。
另请注意,受限 API 不一定稳定:使用 Python 3.8 使用 Py_LIMITED_API
进行编译意味着该扩展将使用 Python 3.12 运行,但不一定使用 Python 3.12 编译 。 特别是,如果稳定 ABI 保持稳定,部分受限 API 可能会被弃用和删除。
平台注意事项
ABI 稳定性不仅取决于 Python,还取决于所使用的编译器、低级库和编译器选项。 出于稳定 ABI 的目的,这些细节定义了一个“平台”。 它们通常取决于操作系统类型和处理器架构
每个特定的 Python 分销商都有责任确保特定平台上的所有 Python 版本都以不破坏稳定 ABI 的方式构建。 python.org
和许多第三方分销商的 Windows 和 macOS 版本就是这种情况。
受限API的内容
目前,Limited API 包括以下项目: