Python C API:用Py_LIMITED_API子类化(内置)类型



我正在尝试移植一个现有的C Python扩展来使用Py_LIMITED_API,这样我们就不必为我们支持的所有Python版本构建扩展。

我面临的一个问题是,这个库提供了pythonfloat类型的子类。

最后一个带有示例的官方文档(https://docs.python.org/3.5/extending/newtypes.html#subclassing-other-types)没有提到有限的API,我面临的问题是,PyFloatObject不是稳定ABI的一部分,这将是创建基本结构所必需的:

typedef struct {
PyFloatObject base;
int state;
} SubclassedFloat;

当使用Py_LIMITED_API时,是否有办法子类化内置类型,特别是float,或者这是不可能的?

这在Python c-extensions的不和中得到了回答:https://discord.com/channels/267624335836053506/728390945384431688/981133468652154920

基本上,你必须在运行时从PyFloat_Type中获取__basicsize__类型属性来声明你的对象大小:

//Code simplified for brevity
struct SubclassedFloatObject
{
// put your data members here
};
Py_ssize_t PyFloat_basicsize = PyLong_AsSsize_t(
PyObject_GetAttrString(
(PyObject*)&PyFloat_Type,
"__basicsize__"));
PyType_Spec SubclassedFloat_spec = {
"SubclassedFloat",                                                      //name
static_cast<int>(PyFloat_basicsize + sizeof(SubclassedFloatObject)),    //basicsize
0,                                                                      //itemsize
Py_TPFLAGS_DEFAULT,                                                     //flags
SubclassedFloat_slots                                                   //slots; /* terminated by slot==0. */
};

当你访问你的对象时,你必须为这个大小偏移PyObject*指针:

int SomePythonFunc(PyObject* self)
{
SubclassedFloat* p_data = (SubclassedFloat*)((uintptr_t)(self) + PyFloat_basicsize);
// do something with p_data
}

最新更新