8000 bpo-44263: Py_TPFLAGS_HAVE_GC requires tp_traverse (GH-26463) · python/cpython@ee76375 · GitHub
[go: up one dir, main page]

Skip to content

Commit ee76375

Browse files
authored
bpo-44263: Py_TPFLAGS_HAVE_GC requires tp_traverse (GH-26463)
The PyType_Ready() function now raises an error if a type is defined with the Py_TPFLAGS_HAVE_GC flag set but has no traverse function (PyTypeObject.tp_traverse).
1 parent fcda0f5 commit ee76375

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

Doc/whatsnew/3.11.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ New Features
144144
Porting to Python 3.11
145145
----------------------
146146

147+
* The :c:func:`PyType_Ready` function now raises an error if a type is defined
148+
with the :const:`Py_TPFLAGS_HAVE_GC` flag set but has no traverse function
149+
(:c:member:`PyTypeObject.tp_traverse`).
150+
(Contributed by Victor Stinner in :issue:`44263`.)
151+
147152
Deprecated
148153
----------
149154

@@ -180,4 +185,4 @@ Removed
180185
parameter of functions :func:`~gettext.translation` and
181186
:func:`~gettext.install` are also removed, since they are only used for
182187
the ``l*gettext()`` functions.
183-
(Contributed by Dong-hee Na and Serhiy Storchaka in :issue:`44235`.)
188+
(Contributed by Dong-hee Na and Serhiy Storchaka in :issue:`44235`.)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The :c:func:`PyType_Ready` function now raises an error if a type is defined
2+
with the :const:`Py_TPFLAGS_HAVE_GC` flag set but has no traverse function
3+
(:c:member:`PyTypeObject.tp_traverse`).
4+
Patch by Victor Stinner.

Objects/typeobject.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ _PyType_CheckConsistency(PyTypeObject *type)
158158
CHECK(!(type->tp_flags & Py_TPFLAGS_READYING));
159159
CHECK(type->tp_dict != NULL);
160160

161+
if (type->tp_flags & Py_TPFLAGS_HAVE_GC) {
162+
// bpo-44263: tp_traverse is required if Py_TPFLAGS_HAVE_GC is set.
163+
// Note: tp_clear is optional.
164+
CHECK(type->tp_traverse != NULL);
165+
}
166+
161167
if (type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION) {
162168
CHECK(type->tp_new == NULL);
163169
CHECK(_PyDict_ContainsId(type->tp_dict, &PyId___new__) == 0);
@@ -3607,6 +3613,7 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
36073613
}
36083614
}
36093615

3616+
assert(_PyType_CheckConsistency(type));
36103617
return (PyObject*)res;
36113618

36123619
fail:
@@ -5944,7 +5951,7 @@ static int add_tp_new_wrapper(PyTypeObject *type);
59445951
#define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
59455952

59465953
static int
5947-
type_ready_checks(PyTypeObject *type)
5954+
type_ready_pre_checks(PyTypeObject *type)
59485955
{
59495956
/* Consistency checks for PEP 590:
59505957
* - Py_TPFLAGS_METHOD_DESCRIPTOR requires tp_descr_get
@@ -6305,10 +6312,28 @@ type_ready_set_new(PyTypeObject *type)
63056312
}
63066313

63076314

6315+
static int
6316+
type_ready_post_checks(PyTypeObject *type)
6317+
{
6318+
// bpo-44263: tp_traverse is required if Py_TPFLAGS_HAVE_GC is set.
6319+
// Note: tp_clear is optional.
6320+
if (type->tp_flags & Py_TPFLAGS_HAVE_GC
6321+
&& type->tp_traverse == NULL)
6322+
{
6323+
PyErr_Format(PyExc_SystemError,
6324+
"type %s has the Py_TPFLAGS_HAVE_GC flag "
6325+
"but has no traverse function",
6326+
type->tp_name);
6327+
return -1;
6328+
}
6329+
return 0;
6330+
}
6331+
6332+
63086333
static int
63096334
type_ready(PyTypeObject *type)
63106335
{
6311-
if (type_ready_checks(type) < 0) {
6336+
if (type_ready_pre_checks(type) < 0) {
63126337
return -1;
63136338
}
63146339

@@ -6346,6 +6371,9 @@ type_ready(PyTypeObject *type)
63466371
if (type_ready_add_subclasses(type) < 0) {
63476372
return -1;
63486373
}
6374+
if (type_ready_post_checks(type) < 0) {
6375+
return -1;
6376+
}
63496377
return 0;
63506378
}
63516379

0 commit comments

Comments
 (0)
0