assert(PyType_Check(type));
PySetObject *so;
- so = (PySetObject *)type->tp_alloc(type, 0);
+ // Allocate untracked: the fill below runs user code, and a half-built
+ // set must not be reachable from another thread via gc.get_objects().
+ so = (PySetObject *)_PyType_AllocNoTrack(type, 0);
if (so == NULL)
return NULL;
}
}
+ // Track only once fully built.
+ _PyObject_GC_TRACK(so);
return (PyObject *)so;
}
0, /* tp_descr_set */
0, /* tp_dictoffset */
set_init, /* tp_init */
- PyType_GenericAlloc, /* tp_alloc */
+ _PyType_AllocNoTrack, /* tp_alloc */
set_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
.tp_vectorcall = set_vectorcall,
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
- PyType_GenericAlloc, /* tp_alloc */
+ _PyType_AllocNoTrack, /* tp_alloc */
frozenset_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
.tp_vectorcall = frozenset_vectorcall,