diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2020-04-27 14:24:31 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-27 14:24:31 (GMT) |
commit | 91a5ae18351027867e99c96db5ea235d9c42e47a (patch) | |
tree | 059fcf1982a6bfa6fbc751a064571c1e8a4bf03d | |
parent | 0169d3003be3d072751dd14a5c84748ab63a249f (diff) | |
download | cpython-91a5ae18351027867e99c96db5ea235d9c42e47a.zip cpython-91a5ae18351027867e99c96db5ea235d9c42e47a.tar.gz cpython-91a5ae18351027867e99c96db5ea235d9c42e47a.tar.bz2 |
bpo-40217: Clean code in PyType_FromSpec_Alloc and add NEWS entry (GH-19733)
-rw-r--r-- | Misc/NEWS.d/next/C API/2020-04-27-14-00-38.bpo-40217.sgn6c8.rst | 5 | ||||
-rw-r--r-- | Objects/typeobject.c | 26 |
2 files changed, 22 insertions, 9 deletions
diff --git a/Misc/NEWS.d/next/C API/2020-04-27-14-00-38.bpo-40217.sgn6c8.rst b/Misc/NEWS.d/next/C API/2020-04-27-14-00-38.bpo-40217.sgn6c8.rst new file mode 100644 index 0000000..72df4a7 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-04-27-14-00-38.bpo-40217.sgn6c8.rst @@ -0,0 +1,5 @@ +Ensure that instances of types created with +:c:func:`PyType_FromSpecWithBases` will visit its class object when +traversing references in the garbage collector (implemented as an extension +of the provided :c:member:`~PyTypeObject.tp_traverse`). Patch by Pablo +Galindo. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 6a9bd70..bf95dd6 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1031,25 +1031,29 @@ PyType_FromSpec_Alloc(PyTypeObject *type, Py_ssize_t nitems) /* note that we need to add one, for the sentinel and space for the provided tp-traverse: See bpo-40217 for more details */ - if (PyType_IS_GC(type)) + if (PyType_IS_GC(type)) { obj = _PyObject_GC_Malloc(size); - else + } + else { obj = (PyObject *)PyObject_MALLOC(size); + } - if (obj == NULL) + if (obj == NULL) { return PyErr_NoMemory(); - - obj = obj; + } memset(obj, '\0', size); - if (type->tp_itemsize == 0) + if (type->tp_itemsize == 0) { (void)PyObject_INIT(obj, type); - else + } + else { (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems); + } - if (PyType_IS_GC(type)) + if (PyType_IS_GC(type)) { _PyObject_GC_TRACK(obj); + } return obj; } @@ -3066,7 +3070,11 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) * * We store the user-provided traverse function at the end of the type * (we have allocated space for it) so we can call it from our - * PyType_FromSpec_tp_traverse wrapper. */ + * PyType_FromSpec_tp_traverse wrapper. + * + * Check bpo-40217 for more information and rationale about this issue. + * + * */ type->tp_traverse = PyType_FromSpec_tp_traverse; size_t _offset = _PyObject_VAR_SIZE(&PyType_Type, nmembers+1); |