]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40217: Clean code in PyType_FromSpec_Alloc and add NEWS entry (GH-19733)
authorPablo Galindo <Pablogsal@gmail.com>
Mon, 27 Apr 2020 14:24:31 +0000 (15:24 +0100)
committerGitHub <noreply@github.com>
Mon, 27 Apr 2020 14:24:31 +0000 (15:24 +0100)
Misc/NEWS.d/next/C API/2020-04-27-14-00-38.bpo-40217.sgn6c8.rst [new file with mode: 0644]
Objects/typeobject.c

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 (file)
index 0000000..72df4a7
--- /dev/null
@@ -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.
index 6a9bd701dfb1787d83883550f34200f05be3d0d4..bf95dd604e58ea651149a8cedccc00b65646d925 100644 (file)
@@ -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);