@@ -1174,6 +1174,23 @@ make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
11741174 return make_new_set (type , iterable );
11751175}
11761176
1177+ void
1178+ _PyFrozenSet_MaybeUntrack (PyObject * op )
1179+ {
1180+ if ((op == NULL ) || !(PyFrozenSet_CheckExact (op ))) {
1181+ return ;
1182+ }
1183+ // the frozenset is tracked by the GC. if all elements are immutable we can untrack
1184+ Py_ssize_t pos = 0 ;
1185+ setentry * entry ;
1186+ while (set_next ((PySetObject * )op , & pos , & entry )) {
1187+ if (_PyObject_GC_MAY_BE_TRACKED (entry -> key )) {
1188+ return ;
1189+ }
1190+ }
1191+ _PyObject_GC_UNTRACK (op );
1192+ }
1193+
11771194static PyObject *
11781195make_new_frozenset (PyTypeObject * type , PyObject * iterable )
11791196{
@@ -1185,7 +1202,9 @@ make_new_frozenset(PyTypeObject *type, PyObject *iterable)
11851202 /* frozenset(f) is idempotent */
11861203 return Py_NewRef (iterable );
11871204 }
1188- return make_new_set (type , iterable );
1205+ PyObject * obj = make_new_set (type , iterable );
1206+ _PyFrozenSet_MaybeUntrack (obj );
1207+ return obj ;
11891208}
11901209
11911210static PyObject *
@@ -2710,7 +2729,11 @@ PySet_New(PyObject *iterable)
27102729PyObject *
27112730PyFrozenSet_New (PyObject * iterable )
27122731{
2713- return make_new_set (& PyFrozenSet_Type , iterable );
2732+ PyObject * result = make_new_set (& PyFrozenSet_Type , iterable );
2733+ if (result != NULL ) {
2734+ _PyFrozenSet_MaybeUntrack (result );
2735+ }
2736+ return result ;
27142737}
27152738
27162739Py_ssize_t
0 commit comments