Skip to content

Commit 42a8e31

Browse files
Skylion007henryiiipre-commit-ci[bot]
authored
Improve Python 3.11 support (#3694)
* Test out Python 3.11 migration * Clean up a bit * Remove todo * Test workaround * Fix potential bug uncovered in 3.11 * Try to fix it more * last ditch fix * Revert. Tp-traverse isn't the problem * Test workaround * Try this hack * Revert MRO changes * Use f_back properly * Qualify auto * Update include/pybind11/pybind11.h * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Simplify code slightly * Ensure co_varnames decref if dict_getitem throws * Eager decref f_code Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 465b2e0 commit 42a8e31

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

include/pybind11/detail/type_caster_base.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,9 +502,10 @@ PYBIND11_NOINLINE std::string error_string() {
502502
}
503503

504504
PyFrameObject *frame = trace->tb_frame;
505+
Py_XINCREF(frame);
505506
errorString += "\n\nAt:\n";
506507
while (frame) {
507-
# if PY_VERSION_HEX >= 0x03090000
508+
# if PY_VERSION_HEX >= 0x030900B1
508509
PyCodeObject *f_code = PyFrame_GetCode(frame);
509510
# else
510511
PyCodeObject *f_code = frame->f_code;
@@ -514,8 +515,15 @@ PYBIND11_NOINLINE std::string error_string() {
514515
errorString += " " + handle(f_code->co_filename).cast<std::string>() + "("
515516
+ std::to_string(lineno)
516517
+ "): " + handle(f_code->co_name).cast<std::string>() + "\n";
517-
frame = frame->f_back;
518518
Py_DECREF(f_code);
519+
# if PY_VERSION_HEX >= 0x030900B1
520+
auto *b_frame = PyFrame_GetBack(frame);
521+
# else
522+
auto *b_frame = frame->f_back;
523+
Py_XINCREF(b_frame);
524+
# endif
525+
Py_DECREF(frame);
526+
frame = b_frame;
519527
}
520528
}
521529
#endif

include/pybind11/pybind11.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2636,19 +2636,19 @@ get_type_override(const void *this_ptr, const type_info *this_type, const char *
26362636

26372637
/* Don't call dispatch code if invoked from overridden function.
26382638
Unfortunately this doesn't work on PyPy. */
2639-
#if !defined(PYPY_VERSION) && PY_VERSION_HEX < 0x030B0000
2640-
// TODO: Remove PyPy workaround for Python 3.11.
2641-
// Current API fails on 3.11 since co_varnames can be null.
2639+
#if !defined(PYPY_VERSION)
26422640
# if PY_VERSION_HEX >= 0x03090000
26432641
PyFrameObject *frame = PyThreadState_GetFrame(PyThreadState_Get());
26442642
if (frame != nullptr) {
26452643
PyCodeObject *f_code = PyFrame_GetCode(frame);
26462644
// f_code is guaranteed to not be NULL
26472645
if ((std::string) str(f_code->co_name) == name && f_code->co_argcount > 0) {
26482646
PyObject *locals = PyEval_GetLocals();
2649-
if (locals != nullptr && f_code->co_varnames != nullptr) {
2650-
PyObject *self_caller
2651-
= dict_getitem(locals, PyTuple_GET_ITEM(f_code->co_varnames, 0));
2647+
if (locals != nullptr) {
2648+
PyObject *co_varnames = PyObject_GetAttrString((PyObject *) f_code, "co_varnames");
2649+
PyObject *self_arg = PyTuple_GET_ITEM(co_varnames, 0);
2650+
Py_DECREF(co_varnames);
2651+
PyObject *self_caller = dict_getitem(locals, self_arg);
26522652
if (self_caller == self.ptr()) {
26532653
Py_DECREF(f_code);
26542654
Py_DECREF(frame);

0 commit comments

Comments
 (0)