@@ -1351,7 +1351,9 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
13511351 assert (PyType_Check (type ));
13521352 PySetObject * so ;
13531353
1354- so = (PySetObject * )type -> tp_alloc (type , 0 );
1354+ // Allocate untracked: the fill below runs user code, and a half-built
1355+ // set must not be reachable from another thread via gc.get_objects().
1356+ so = (PySetObject * )_PyType_AllocNoTrack (type , 0 );
13551357 if (so == NULL )
13561358 return NULL ;
13571359
@@ -1370,6 +1372,8 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
13701372 }
13711373 }
13721374
1375+ // Track only once fully built.
1376+ _PyObject_GC_TRACK (so );
13731377 return (PyObject * )so ;
13741378}
13751379
@@ -2875,7 +2879,7 @@ PyTypeObject PySet_Type = {
28752879 0 , /* tp_descr_set */
28762880 0 , /* tp_dictoffset */
28772881 set_init , /* tp_init */
2878- PyType_GenericAlloc , /* tp_alloc */
2882+ _PyType_AllocNoTrack , /* tp_alloc */
28792883 set_new , /* tp_new */
28802884 PyObject_GC_Del , /* tp_free */
28812885 .tp_vectorcall = set_vectorcall ,
@@ -2967,7 +2971,7 @@ PyTypeObject PyFrozenSet_Type = {
29672971 0 , /* tp_descr_set */
29682972 0 , /* tp_dictoffset */
29692973 0 , /* tp_init */
2970- PyType_GenericAlloc , /* tp_alloc */
2974+ _PyType_AllocNoTrack , /* tp_alloc */
29712975 frozenset_new , /* tp_new */
29722976 PyObject_GC_Del , /* tp_free */
29732977 .tp_vectorcall = frozenset_vectorcall ,
0 commit comments