From 97e36b55ed62d95574c00ef5afd12943f9cad9a2 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Mon, 25 Jul 2022 20:09:55 +0800 Subject: [PATCH] Fix MRO calculation for types with manual __dict__ --- .../2022-07-25-20-09-21.gh-issue-92678.8IfNdU.rst | 2 ++ Objects/typeobject.c | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-07-25-20-09-21.gh-issue-92678.8IfNdU.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-25-20-09-21.gh-issue-92678.8IfNdU.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-25-20-09-21.gh-issue-92678.8IfNdU.rst new file mode 100644 index 00000000000000..636ef4b1492da6 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-25-20-09-21.gh-issue-92678.8IfNdU.rst @@ -0,0 +1,2 @@ +Fix MRO calculation issue which caused C extension types manually managing +their own ``__dict__`` to fail in Python 3.11. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 5ebff6084f4a97..fdf5014cc4edcf 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2241,6 +2241,12 @@ extra_ivars(PyTypeObject *type, PyTypeObject *base) type->tp_weaklistoffset + sizeof(PyObject *) == t_size && type->tp_flags & Py_TPFLAGS_HEAPTYPE) t_size -= sizeof(PyObject *); + if (!(type->tp_flags & Py_TPFLAGS_MANAGED_DICT) && + type->tp_dictoffset && base->tp_dictoffset == 0 && + type->tp_dictoffset + sizeof(PyObject *) == t_size && + type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + t_size -= sizeof(PyObject *); + } return t_size != b_size; }