mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
GH-92678: Fix tp_dictoffset inheritance. (GH-95596)
* Add test for inheriting explicit __dict__ and weakref. * Restore 3.10 behavior for multiple inheritance of C extension classes that store their dictionary at the end of the struct.
This commit is contained in:
parent
89f5229328
commit
906e450932
4 changed files with 65 additions and 3 deletions
|
@ -2316,6 +2316,11 @@ best_base(PyObject *bases)
|
|||
return base;
|
||||
}
|
||||
|
||||
#define ADDED_FIELD_AT_OFFSET(name, offset) \
|
||||
(type->tp_ ## name && (base->tp_ ##name == 0) && \
|
||||
type->tp_ ## name + sizeof(PyObject *) == (offset) && \
|
||||
type->tp_flags & Py_TPFLAGS_HEAPTYPE)
|
||||
|
||||
static int
|
||||
extra_ivars(PyTypeObject *type, PyTypeObject *base)
|
||||
{
|
||||
|
@ -2328,10 +2333,18 @@ extra_ivars(PyTypeObject *type, PyTypeObject *base)
|
|||
return t_size != b_size ||
|
||||
type->tp_itemsize != base->tp_itemsize;
|
||||
}
|
||||
if (type->tp_weaklistoffset && base->tp_weaklistoffset == 0 &&
|
||||
type->tp_weaklistoffset + sizeof(PyObject *) == t_size &&
|
||||
type->tp_flags & Py_TPFLAGS_HEAPTYPE)
|
||||
/* Check for __dict__ and __weakrefs__ slots in either order */
|
||||
if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) {
|
||||
t_size -= sizeof(PyObject *);
|
||||
}
|
||||
if ((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0 &&
|
||||
ADDED_FIELD_AT_OFFSET(dictoffset, t_size)) {
|
||||
t_size -= sizeof(PyObject *);
|
||||
}
|
||||
/* Check __weakrefs__ again, in case it precedes __dict__ */
|
||||
if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) {
|
||||
t_size -= sizeof(PyObject *);
|
||||
}
|
||||
return t_size != b_size;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue