jcea
jcea

Reputation: 688

Can a Python heap time created with "PyType_FromSpec()" be weak reference compatible

Migrating a C module extension for Python to Py_LIMITED_API (PEP 384) I am moving my static types to heap types created with "PyType_FromSpec()". It works so far, but my previous types were weakref compatible and I don't know how to make new heap types weakref compatible.

My code is something like:

static PyType_Slot DBLogCursor_Type_slots[] = {
    {Py_tp_dealloc, DBLogCursor_dealloc},
    {Py_tp_methods, DBLogCursor_methods},
    {0, NULL},
};

static PyType_Spec DBLogCursor_Type_spec = {
    .name = PY_BERKELEYDB_BASE "DBLogCursor",
    .basicsize = sizeof(DBLogCursorObject),
    .itemsize = 0,
    .flags = Py_TPFLAGS_DEFAULT,
    .slots = DBLogCursor_Type_slots,
};

static PyTypeObject *DBLogCursor_Type = NULL;

[...]

    /* Initialize object types */
    type = (PyTypeObject)PyType_FromSpec(&DBLogCursor_Type_spec);
    if (type == NULL)
        return NULL;
    type->tp_new = NULL;
    DBLogCursor_Type = type;

Test suite is successful except weakref test:

[...]
  File "/tmp/ram/pybsddb/build/lib.linux-x86_64-3.6/berkeleydb/tests/test_weakref.py", line 76, in _test
    ref = weakref.ref(obj)
TypeError: cannot create weak reference to 'berkeleydb._berkeleydb.DBLogCursor' object

What can I do?

Thanks!

EDITION

Reading the CPython source code, I have done this change:

static PyMemberDef DBLogCursor_Type_members[] = {
    {"__weaklistoffset__", T_PYSSIZET,
        offsetof(DBLogCursorObject, in_weakreflist), READONLY},
    {NULL},
};

static PyType_Slot DBLogCursor_Type_slots[] = {
    {Py_tp_dealloc, DBLogCursor_dealloc},
    {Py_tp_methods, DBLogCursor_methods},
    {Py_tp_members, DBLogCursor_Type_members},
    {0, NULL},
};

Still no luck:

TypeError: cannot create weak reference to 'berkeleydb._berkeleydb.DBLogCursor' object

Upvotes: 0

Views: 367

Answers (1)

jcea
jcea

Reputation: 688

Problem found: The last version posted works... under Python 3.9. It doesn't work in previous Python 3.x releases.

I was checking Python 3.9 source code trying to triage this, but I was testing my code under Python 3.6.

I guess I can not create weakref compatible heap types in python3 < 3.9.

Details:

Py_tp_dictoffset / Py_tp_finalize are unsettable in stable API

bpo-38140: Make dict and weakref offsets opaque for C heap types (#16076)

Upvotes: 0

Related Questions