内容提要
PEP 741 提议为 Python 3.13 新增配置 C API,并纳入受限 C API 与稳定 ABI。其核心是 PyInitConfig 结构,统一预初始化与初始化配置,提供设置整数、字符串、字符串列表等函数,并支持错误与退出码处理。新增 PyConfig_Get 和 sys.get_config() 读取当前配置,允许第三方自定义选项。该 API 向后兼容,仅新增接口,解决 PyConfig 不属受限 API 及旧配置 API 已弃用等问题。
延伸解读
为何需要新的配置 C API
PEP 587 引入的 PyConfig 结构未版本化,无法保证 ABI 兼容,因此被排除在受限 C API 和稳定 ABI 之外。随着 PyO3 等 Rust 绑定项目越来越多地使用受限 C API 嵌入 Python,它们需要一种既能配置初始化又能读取当前配置的稳定接口。同时,旧版配置 API 自 Python 3.8 起逐步弃用,且 PEP 587 本身没有提供获取当前配置的公开方法,这促使 PEP 741 将预初始化与初始化配置统一到新的 PyInitConfig 结构中。
对嵌入 Python 的开发者意味着什么
新 API 全部加入受限 C API 3.13,意味着使用稳定 ABI 的扩展或嵌入程序可以直接调用 PyInitConfig 系列函数来设置整数、字符串和字符串列表等选项,并通过 Py_InitializeFromInitConfig 完成初始化。错误处理被整合进配置结构,可用 PyInitConfig_GetError 和 PyInitConfig_GetExitCode 获取错误信息与退出码。此外,PyConfig_Get 和 sys.get_config() 让开发者能读取当前配置值,弥补了此前只能写不能读
自定义选项与命名约定
PEP 741 允许第三方通过设置 allow_custom_options 为 1 来启用自定义配置选项,这些选项不被 Python 自身使用,但可由第三方代码通过 PyInitConfig_SetInt 等函数设置,之后用 PyConfig_Get 读取。为避免与未来 Python 官方选项冲突,建议使用带冒号前缀的名称,例如应用 myapp 可使用 "myapp:verbose"。默认情况下不允许设置未知选项,这有助于及早发现拼写错误或误用。
设计取舍与兼容性
该提案仅新增接口,不改动现有 PyConfig API,因此完全向后兼容。被拒绝的方案包括以文本形式传递配置,因为需要处理引号和转义,格式化字符串数组较为繁琐;以及用整数引用选项,虽然比较更快,但难以维护命名空间且容易冲突。提案认为 Python 3.13 仅有约 62 个配置选项,字符串比较的性能开销并非瓶颈,必要时可缓存读取结果。
Q&A
PEP 741 是什么?它主要解决什么问题?
PEP 741 提议为 Python 3.13 新增配置 C API,并纳入受限 C API 与稳定 ABI。它主要解决 PyConfig 不属于受限 API、旧配置 API 已弃用、以及缺乏获取当前配置的公共 API 等问题。
PyInitConfig 结构有什么作用?它包含哪些部分?
PyInitConfig 是一个不透明结构,用于统一配置 Python 的预初始化和初始化。它由 PyPreConfig、PyConfig 和 PyStatus 三个结构组合而成,使 API 更易使用。
如何使用新的 C API 设置配置选项?请举例说明。
可以使用 PyInitConfig_SetInt、PyInitConfig_SetStr、PyInitConfig_SetWStr、PyInitConfig_SetStrList、PyInitConfig_SetWStrList 等函数设置不同类型的选项。例如,设置整数选项 dev_mode:PyInitConfig_SetInt(config, "dev_mode", 1);设置宽字符串列表 argv:PyInitConfig_SetWStrList(config, "argv", length, argv)。
如何获取 Python 当前的配置值?
可以通过 PyConfig_Get(name) 获取配置选项的当前值(返回对象),或使用 PyConfig_GetInt(name, &value) 获取整数值。在 Python 层面,可以调用 sys.get_config(name) 函数。
PEP 741 允许第三方自定义配置选项吗?如何避免冲突?
允许。通过调用 PyInitConfig_SetInt(config, "allow_custom_options", 1) 开启自定义选项支持。为避免与未来 Python 选项冲突,建议使用带冒号的前缀,例如 "myapp:verbose"。
PEP 741 的向后兼容性如何?
PEP 741 完全向后兼容,仅新增 API,不修改现有 API(如 PyConfig C API)。