@@ -1137,14 +1137,14 @@ set_update_impl(PySetObject *so, PyObject * const *others,
11371137 can be retrieved or updated in a single cache line.
11381138*/
11391139
1140+ // Build a set/frozenset left GC-untracked; the caller must _PyObject_GC_TRACK()
1141+ // it once fully built, so a half-built set is never exposed during filling.
11401142static PyObject *
1141- make_new_set (PyTypeObject * type , PyObject * iterable )
1143+ make_new_set_untracked (PyTypeObject * type , PyObject * iterable )
11421144{
11431145 assert (PyType_Check (type ));
11441146 PySetObject * so ;
11451147
1146- // Allocate untracked: the fill below runs user code, and a half-built
1147- // set must not be reachable from another thread via gc.get_objects().
11481148 so = (PySetObject * )_PyType_AllocNoTrack (type , 0 );
11491149 if (so == NULL )
11501150 return NULL ;
@@ -1164,21 +1164,39 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
11641164 }
11651165 }
11661166
1167- // Track only once fully built.
1168- _PyObject_GC_TRACK (so );
11691167 return (PyObject * )so ;
11701168}
11711169
11721170static PyObject *
1173- make_new_set_basetype (PyTypeObject * type , PyObject * iterable )
1171+ make_new_set (PyTypeObject * type , PyObject * iterable )
1172+ {
1173+ PyObject * so = make_new_set_untracked (type , iterable );
1174+ if (so != NULL ) {
1175+ _PyObject_GC_TRACK (so );
1176+ }
1177+ return so ;
1178+ }
1179+
1180+ static PyObject *
1181+ make_new_set_basetype_untracked (PyTypeObject * type , PyObject * iterable )
11741182{
11751183 if (type != & PySet_Type && type != & PyFrozenSet_Type ) {
11761184 if (PyType_IsSubtype (type , & PySet_Type ))
11771185 type = & PySet_Type ;
11781186 else
11791187 type = & PyFrozenSet_Type ;
11801188 }
1181- return make_new_set (type , iterable );
1189+ return make_new_set_untracked (type , iterable );
1190+ }
1191+
1192+ static PyObject *
1193+ make_new_set_basetype (PyTypeObject * type , PyObject * iterable )
1194+ {
1195+ PyObject * so = make_new_set_basetype_untracked (type , iterable );
1196+ if (so != NULL ) {
1197+ _PyObject_GC_TRACK (so );
1198+ }
1199+ return so ;
11821200}
11831201
11841202static PyObject *
@@ -1423,7 +1441,7 @@ set_intersection(PySetObject *so, PyObject *other)
14231441 if ((PyObject * )so == other )
14241442 return set_copy_impl (so );
14251443
1426- result = (PySetObject * )make_new_set_basetype (Py_TYPE (so ), NULL );
1444+ result = (PySetObject * )make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
14271445 if (result == NULL )
14281446 return NULL ;
14291447
@@ -1456,6 +1474,7 @@ set_intersection(PySetObject *so, PyObject *other)
14561474 }
14571475 Py_DECREF (key );
14581476 }
1477+ _PyObject_GC_TRACK (result );
14591478 return (PyObject * )result ;
14601479 }
14611480
@@ -1487,6 +1506,7 @@ set_intersection(PySetObject *so, PyObject *other)
14871506 Py_DECREF (result );
14881507 return NULL ;
14891508 }
1509+ _PyObject_GC_TRACK (result );
14901510 return (PyObject * )result ;
14911511 error :
14921512 Py_DECREF (it );
@@ -1801,7 +1821,7 @@ set_difference(PySetObject *so, PyObject *other)
18011821 return set_copy_and_difference (so , other );
18021822 }
18031823
1804- result = make_new_set_basetype (Py_TYPE (so ), NULL );
1824+ result = make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
18051825 if (result == NULL )
18061826 return NULL ;
18071827
@@ -1825,6 +1845,7 @@ set_difference(PySetObject *so, PyObject *other)
18251845 }
18261846 Py_DECREF (key );
18271847 }
1848+ _PyObject_GC_TRACK (result );
18281849 return result ;
18291850 }
18301851
@@ -1848,6 +1869,7 @@ set_difference(PySetObject *so, PyObject *other)
18481869 }
18491870 Py_DECREF (key );
18501871 }
1872+ _PyObject_GC_TRACK (result );
18511873 return result ;
18521874}
18531875
@@ -2037,7 +2059,8 @@ static PyObject *
20372059set_symmetric_difference_impl (PySetObject * so , PyObject * other )
20382060/*[clinic end generated code: output=270ee0b5d42b0797 input=624f6e7bbdf70db1]*/
20392061{
2040- PySetObject * result = (PySetObject * )make_new_set_basetype (Py_TYPE (so ), NULL );
2062+ PySetObject * result =
2063+ (PySetObject * )make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
20412064 if (result == NULL ) {
20422065 return NULL ;
20432066 }
@@ -2049,6 +2072,7 @@ set_symmetric_difference_impl(PySetObject *so, PyObject *other)
20492072 Py_DECREF (result );
20502073 return NULL ;
20512074 }
2075+ _PyObject_GC_TRACK (result );
20522076 return (PyObject * )result ;
20532077}
20542078
0 commit comments