Python C API:py_limited_api的子分类(内置)类型

发布于 2025-02-01 05:18:45 字数 635 浏览 4 评论 0 原文

我正在尝试将现有的C Python扩展程序移植以使用 py_limited_api ,这样我们就不必为我们支持的所有Python版本构建扩展程序。

我面临的问题之一是,该库提供了一种类型,该类型属于Python float 类型。

最后的官方文档中带有示例()没有提及有限的API,我面临的问题是, pyfloatObject 不是属于稳定的ABI,这是创建基本结构的必要

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

条件:使用 py_limited_api ,尤其是 float ,还是不可能?

I am trying to port an existing C Python extension to use the Py_LIMITED_API, so that we don't have to build the extension for all the python versions we support.

One of the issues I'm facing is, that this library provides a type that subclasses the python float type.

The last official documentation with examples ( https://docs.python.org/3.5/extending/newtypes.html#subclassing-other-types) does not mention the limited API, and I'm facing the problem, that PyFloatObject is not part of the stable ABI, which would be necessary to create the base struct:

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

Is there a way to subclass a builtin type when using Py_LIMITED_API, especially float, or is this impossible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

み格子的夏天 2025-02-08 05:18:45

这在python c extensions Cornord上得到了回答:

基本上,您必须从 pyfloat_type 在运行时获取 __基础化__ 键入属性,以声明您的对象大小:

//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*< pyobject*<<<<<<<<< /代码>此大小的指针:

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

This was answered on the Python c-extensions discord:
https://discord.com/channels/267624335836053506/728390945384431688/981133468652154920

Basically, you have to fetch the __basicsize__ type attribute from PyFloat_Type at runtime to declare your object size:

//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. */
};

Whenever you access your object, you'll have to offset the PyObject* pointer for this size:

int SomePythonFunc(PyObject* self)
{
    SubclassedFloat* p_data = (SubclassedFloat*)((uintptr_t)(self) + PyFloat_basicsize);
    // do something with p_data
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文