bpo-38140: Make dict and weakref offsets opaque for C heap types (#16076)

* Make dict and weakref offsets opaque for C heap types

* Add news
This commit is contained in:
Eddie Elizondo 2019-09-19 09:29:05 -07:00 committed by Dino Viehland
parent 079931d122
commit 3368f3c6ae
8 changed files with 188 additions and 8 deletions

View file

@ -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) {