如何禁用Python的Py_LIMITED_API?相关配置编译标志说明
首先来解决你最关心的第一个问题:哪些编译/配置标志控制Py_LIMITED_API?
你可以通过三种方式启用这个编译选项:
- 在C源码中直接定义宏:在引入
<Python.h>之前添加一行#define Py_LIMITED_API,如果需要指定兼容的最低Python版本,还可以加上版本号,比如#define Py_LIMITED_API 0x03050000(对应Python 3.5及以上) - 编译命令行参数:使用gcc等编译器时,通过
-DPy_LIMITED_API(或-DPy_LIMITED_API=0x03050000)来传递宏定义 - 使用setuptools构建扩展:在
setup.py的Extension配置里添加define_macros=[('Py_LIMITED_API', '0x03050000')],构建工具会自动把这个宏传递给编译器
接下来聊聊你提到的Buffer API依赖Py_LIMITED_API的困惑:
这里可能存在一点误解——Py_LIMITED_API的作用是让你的扩展只使用Python的「稳定ABI」子集,而Buffer API(比如PyBuffer_GetPointer、PyBuffer_Release这类PyBuffer_*系列函数)本身就是稳定ABI的一部分。
如果你的代码在不启用Py_LIMITED_API时无法编译Buffer相关代码,大概率是因为你误用了仅在稳定ABI模式下才暴露的宏/接口,或者你的代码依赖了某个需要特定版本定义的Buffer API细节。反过来,不启用Py_LIMITED_API时,编译器会使用当前Python版本的完整API,理论上应该能访问所有Buffer相关接口才对。
关于默认设置与文档说明:
Py_LIMITED_API默认是不启用的,它是一个可选选项,核心目的是让扩展模块能跨多个Python版本兼容(利用稳定ABI)。如果你的扩展不需要跨版本部署,完全没必要开启它。
至于文档未提及部分API依赖这个设置的问题,可能是你没找到对应的章节——Python官方文档在「扩展与嵌入Python」部分,专门有关于稳定ABI的说明,里面会明确哪些API属于受限子集,以及启用Py_LIMITED_API后的行为变化。
最后说说Python 3.5编译失败的问题:
Buffer API在Python 3.5中已经存在,但部分接口的签名或宏定义和更高版本有差异。比如某些3.6+才新增的Buffer相关函数(如PyBuffer_IsContiguous的某些参数变体)在3.5中是没有的。建议你仔细查看编译错误信息,定位到具体未定义的函数/宏,再对照Python 3.5的C API文档调整代码,确保使用的是3.5支持的接口。
内容的提问来源于stack exchange,提问作者wvxvw

