Skip to content

Commit 91a5ae1

Browse files
authored
bpo-40217: Clean code in PyType_FromSpec_Alloc and add NEWS entry (GH-19733)
1 parent 0169d30 commit 91a5ae1

File tree

2 files changed

+22
-9
lines changed

2 files changed

+22
-9
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Ensure that instances of types created with
2+
:c:func:`PyType_FromSpecWithBases` will visit its class object when
3+
traversing references in the garbage collector (implemented as an extension
4+
of the provided :c:member:`~PyTypeObject.tp_traverse`). Patch by Pablo
5+
Galindo.

Objects/typeobject.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,25 +1031,29 @@ PyType_FromSpec_Alloc(PyTypeObject *type, Py_ssize_t nitems)
10311031
/* note that we need to add one, for the sentinel and space for the
10321032
provided tp-traverse: See bpo-40217 for more details */
10331033

1034-
if (PyType_IS_GC(type))
1034+
if (PyType_IS_GC(type)) {
10351035
obj = _PyObject_GC_Malloc(size);
1036-
else
1036+
}
1037+
else {
10371038
obj = (PyObject *)PyObject_MALLOC(size);
1039+
}
10381040

1039-
if (obj == NULL)
1041+
if (obj == NULL) {
10401042
return PyErr_NoMemory();
1041-
1042-
obj = obj;
1043+
}
10431044

10441045
memset(obj, '\0', size);
10451046

1046-
if (type->tp_itemsize == 0)
1047+
if (type->tp_itemsize == 0) {
10471048
(void)PyObject_INIT(obj, type);
1048-
else
1049+
}
1050+
else {
10491051
(void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);
1052+
}
10501053

1051-
if (PyType_IS_GC(type))
1054+
if (PyType_IS_GC(type)) {
10521055
_PyObject_GC_TRACK(obj);
1056+
}
10531057
return obj;
10541058
}
10551059

@@ -3066,7 +3070,11 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
30663070
*
30673071
* We store the user-provided traverse function at the end of the type
30683072
* (we have allocated space for it) so we can call it from our
3069-
* PyType_FromSpec_tp_traverse wrapper. */
3073+
* PyType_FromSpec_tp_traverse wrapper.
3074+
*
3075+
* Check bpo-40217 for more information and rationale about this issue.
3076+
*
3077+
* */
30703078

30713079
type->tp_traverse = PyType_FromSpec_tp_traverse;
30723080
size_t _offset = _PyObject_VAR_SIZE(&PyType_Type, nmembers+1);

0 commit comments

Comments
 (0)