diff options
author | Eddie Elizondo <eelizondo@fb.com> | 2019-09-19 16:29:05 (GMT) |
---|---|---|
committer | Dino Viehland <dinoviehland@gmail.com> | 2019-09-19 16:29:05 (GMT) |
commit | 3368f3c6ae4140a0883e19350e672fd09c9db616 (patch) | |
tree | 0b4477fdd89aefa2b9d17e6a16c3f172f32a5660 /Objects | |
parent | 079931d12223ec98cbf53185b90db48efa61f93f (diff) | |
download | cpython-3368f3c6ae4140a0883e19350e672fd09c9db616.zip cpython-3368f3c6ae4140a0883e19350e672fd09c9db616.tar.gz cpython-3368f3c6ae4140a0883e19350e672fd09c9db616.tar.bz2 |
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
Diffstat (limited to 'Objects')
-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) { |