diff options
Diffstat (limited to 'Objects/typeobject.c')
-rw-r--r-- | Objects/typeobject.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index dfdac9e..94a4da2 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2853,15 +2853,27 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) PyTypeObject *type, *base; PyType_Slot *slot; - Py_ssize_t nmembers; + Py_ssize_t nmembers, weaklistoffset, dictoffset; char *s, *res_start; - nmembers = 0; + nmembers = weaklistoffset = dictoffset = 0; for (slot = spec->slots; slot->slot; slot++) { if (slot->slot == Py_tp_members) { nmembers = 0; for (memb = slot->pfunc; memb->name != NULL; memb++) { nmembers++; + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + // The PyMemberDef must be a Py_ssize_t and readonly + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + weaklistoffset = memb->offset; + } + if (strcmp(memb->name, "__dictoffset__") == 0) { + // The PyMemberDef must be a Py_ssize_t and readonly + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + dictoffset = memb->offset; + } } } } @@ -2990,6 +3002,17 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) res->ht_cached_keys = _PyDict_NewKeysForClass(); } + if (weaklistoffset) { + type->tp_weaklistoffset = weaklistoffset; + if (PyDict_DelItemString((PyObject *)type->tp_dict, "__weaklistoffset__") < 0) + goto fail; + } + if (dictoffset) { + type->tp_dictoffset = dictoffset; + if (PyDict_DelItemString((PyObject *)type->tp_dict, "__dictoffset__") < 0) + goto fail; + } + /* Set type.__module__ */ s = strrchr(spec->name, '.'); if (s != NULL) { |