pybind / pybind11

Seamless operability between C++11 and Python
https://pybind11.readthedocs.io/
Other
15.08k stars 2.05k forks source link

fix: support Python 3.13.0b1 (PEP 667 fix) #5127

Closed henryiii closed 1 month ago

henryiii commented 1 month ago

Description

Since beta 1 is out, time to start testing all the time on Python 3.13, not just PR’s with a dev label.

Suggested changelog entry:

* Run CI on Python 3.13
henryiii commented 1 month ago

Some destructors are not being called when they used to be. The following three tests break:

FAILED ../../tests/test_factory_constructors.py::test_init_factory_alias - assert [3, 3] == [0, 0]
FAILED ../../tests/test_factory_constructors.py::test_init_factory_dual - assert [9, 6] == [7, 4]
FAILED ../../tests/test_virtual_functions.py::test_override - assert 2 == 0

In these, .alive() is called, which runs the gc, then the number of times .destroyed() is called is less on 3.13.0b1 than 3.13.0a6.

Running git bisect between v3.13.0a6 and v3.13.0b1 with the follow script:

#/usr/bin/env bash
set -euo pipefail

./configure --prefix $PWD/../python
make -j8
make install -j8

cd ..
uv pip install --python=./Python/bin/python3 pytest
cmake -S. -Bbuild -DPython_ROOT_DIR=Python -DPYBIND11_TEST_OVERRIDE='test_factory_constructors.py;test_virtual_functions.py'
cmake --build build --target pytest

Showed this broke with https://github.com/python/cpython/pull/115153, PEP 667.

These are now replaced with new functions:

$ git grep -E 'PyEval_GetLocals|PyEval_GetGlobals|PyEval_GetBuiltins|\.f_locals'
include/pybind11/detail/internals.h:446:    state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
include/pybind11/pybind11.h:1347:    PyObject *p = PyEval_GetGlobals();
include/pybind11/pybind11.h:2773:            PyObject *locals = PyEval_GetLocals();
include/pybind11/pybind11.h:2820:                       "        self_caller = frame.f_locals[frame.f_code.co_varnames[0]]\n"
tests/constructor_stats.h:116:        PyObject *globals = PyEval_GetGlobals();

These are now no-ops:

$ git grep -E 'PyFrame_FastToLocalsWithError|PyFrame_FastToLocals|git grep PyFrame_LocalsToFast'
include/pybind11/pybind11.h:2797:        PyFrame_FastToLocals(frame);

If I update to use the new functions (only a couple of instances, the rest are for PyPy), then nothing changes (Edit: never mind, messed up the version number, forgot a 0).

henryiii commented 1 month ago

FYI, four tests fail (related to refcounts) when using free-threaded 3.13 but holding the GIL.