pybind / pybind11

Seamless operability between C++11 and Python

Home Page:https://pybind11.readthedocs.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG]: make_static_property_type() is incompatible with Python 3.13 ands leads to a crash

vstinner opened this issue · comments

Required prerequisites

What version (or hash if on master) of pybind11 are you using?

2.11.1

Problem description

Running python-contourpy tests on Python 3.13 does crash. Using a Python debug build, the following assertion fails:

+ python3-debug -c 'import contourpy'
python3-debug: /builddir/build/BUILD/Python-3.13.0a2/Objects/dictobject.c:5473: _PyObject_InitInlineValues: Assertion `keys != NULL' failed.

The problem is the pybind11_static_property type created as a Python heap type in make_static_property_type() of pybind11/include/pybind11/detail/class.h which sets the Py_TPFLAGS_MANAGED_DICT flag after calling PyType_Ready(). Maybe it worked on Python 3.12, but it no longer works on Python 3.13 which requires the flag to be set before calling PyType_Ready().

Fedora downstream issue about the contourpy crash: https://bugzilla.redhat.com/show_bug.cgi?id=2252083

Note: I tested the Fedora package python3-pybind11-2.11.1-1.fc40.x86_64.

Reproducible example code

I'm sorry, right now I have no short reproducer :-(

Is this a regression? Put the last known working version here if it is.

Work on Python 3.12, crash on Python 3.13

The issue is quite tricky. Context:

I wrote #4971 to fix the issue.

By the way, the following code in include/pybind11/detail/class.h can now be updated to use the new function: PyObject_VisitManagedDict() (new in Python 3.13)

extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) {
    PyObject *&dict = *_PyObject_GetDictPtr(self);
    Py_VISIT(dict);

And the following code can be updated to use: PyObject_ClearManagedDict() (new in Python 3.13)

extern "C" inline int pybind11_clear(PyObject *self) {
    PyObject *&dict = *_PyObject_GetDictPtr(self);
    Py_CLEAR(dict);

By the way, the following code in include/pybind11/detail/class.h can now be updated

Is there a chance that you could send a PR with that change?

Is there a chance that you could send a PR with that change?

I created #4973 to use PyObject_VisitManagedDict() and PyObject_ClearManagedDict().

Closed by #4973