@@ -1567,6 +1567,21 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
15671567 FT_ATOMIC_STORE_PTR_RELEASE (b -> table , b_table );
15681568}
15691569
1570+ static PyObject *
1571+ set_copy_untracked_lock_held (PySetObject * so )
1572+ {
1573+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (so );
1574+ PyObject * copy = make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
1575+ if (copy == NULL ) {
1576+ return NULL ;
1577+ }
1578+ if (set_merge_lock_held ((PySetObject * )copy , (PyObject * )so ) < 0 ) {
1579+ Py_DECREF (copy );
1580+ return NULL ;
1581+ }
1582+ return copy ;
1583+ }
1584+
15701585/*[clinic input]
15711586@critical_section
15721587set.copy
@@ -1579,14 +1594,9 @@ static PyObject *
15791594set_copy_impl (PySetObject * so )
15801595/*[clinic end generated code: output=c9223a1e1cc6b041 input=c169a4fbb8209257]*/
15811596{
1582- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (so );
1583- PyObject * copy = make_new_set_basetype (Py_TYPE (so ), NULL );
1584- if (copy == NULL ) {
1585- return NULL ;
1586- }
1587- if (set_merge_lock_held ((PySetObject * )copy , (PyObject * )so ) < 0 ) {
1588- Py_DECREF (copy );
1589- return NULL ;
1597+ PyObject * copy = set_copy_untracked_lock_held (so );
1598+ if (copy != NULL ) {
1599+ _PyObject_GC_TRACK (copy );
15901600 }
15911601 return copy ;
15921602}
@@ -1642,7 +1652,8 @@ set_union_impl(PySetObject *so, PyObject * const *others,
16421652 PyObject * other ;
16431653 Py_ssize_t i ;
16441654
1645- result = (PySetObject * )set_copy ((PyObject * )so , NULL );
1655+ result = (PySetObject * )make_new_set_basetype_untracked (Py_TYPE (so ),
1656+ (PyObject * )so );
16461657 if (result == NULL )
16471658 return NULL ;
16481659
@@ -1655,6 +1666,7 @@ set_union_impl(PySetObject *so, PyObject * const *others,
16551666 return NULL ;
16561667 }
16571668 }
1669+ _PyObject_GC_TRACK (result );
16581670 return (PyObject * )result ;
16591671}
16601672
@@ -2045,11 +2057,11 @@ set_difference_update_impl(PySetObject *so, PyObject * const *others,
20452057}
20462058
20472059static PyObject *
2048- set_copy_and_difference (PySetObject * so , PyObject * other )
2060+ set_copy_and_difference_untracked (PySetObject * so , PyObject * other )
20492061{
20502062 PyObject * result ;
20512063
2052- result = set_copy_impl (so );
2064+ result = set_copy_untracked_lock_held (so );
20532065 if (result == NULL )
20542066 return NULL ;
20552067 if (set_difference_update_internal ((PySetObject * ) result , other ) == 0 )
@@ -2059,7 +2071,7 @@ set_copy_and_difference(PySetObject *so, PyObject *other)
20592071}
20602072
20612073static PyObject *
2062- set_difference (PySetObject * so , PyObject * other )
2074+ set_difference_untracked (PySetObject * so , PyObject * other )
20632075{
20642076 PyObject * result ;
20652077 PyObject * key ;
@@ -2075,13 +2087,13 @@ set_difference(PySetObject *so, PyObject *other)
20752087 other_size = PyDict_GET_SIZE (other );
20762088 }
20772089 else {
2078- return set_copy_and_difference (so , other );
2090+ return set_copy_and_difference_untracked (so , other );
20792091 }
20802092
20812093 /* If len(so) much more than len(other), it's more efficient to simply copy
20822094 * so and then iterate other looking for common elements. */
20832095 if ((PySet_GET_SIZE (so ) >> 2 ) > other_size ) {
2084- return set_copy_and_difference (so , other );
2096+ return set_copy_and_difference_untracked (so , other );
20852097 }
20862098
20872099 result = make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
@@ -2108,7 +2120,6 @@ set_difference(PySetObject *so, PyObject *other)
21082120 }
21092121 Py_DECREF (key );
21102122 }
2111- _PyObject_GC_TRACK (result );
21122123 return result ;
21132124 }
21142125
@@ -2132,7 +2143,6 @@ set_difference(PySetObject *so, PyObject *other)
21322143 }
21332144 Py_DECREF (key );
21342145 }
2135- _PyObject_GC_TRACK (result );
21362146 return result ;
21372147}
21382148
@@ -2159,7 +2169,7 @@ set_difference_multi_impl(PySetObject *so, PyObject * const *others,
21592169
21602170 other = others [0 ];
21612171 Py_BEGIN_CRITICAL_SECTION2 (so , other );
2162- result = set_difference (so , other );
2172+ result = set_difference_untracked (so , other );
21632173 Py_END_CRITICAL_SECTION2 ();
21642174 if (result == NULL )
21652175 return NULL ;
@@ -2175,6 +2185,7 @@ set_difference_multi_impl(PySetObject *so, PyObject * const *others,
21752185 return NULL ;
21762186 }
21772187 }
2188+ _PyObject_GC_TRACK (result );
21782189 return result ;
21792190}
21802191
@@ -2187,8 +2198,11 @@ set_sub(PyObject *self, PyObject *other)
21872198
21882199 PyObject * rv ;
21892200 Py_BEGIN_CRITICAL_SECTION2 (so , other );
2190- rv = set_difference (so , other );
2201+ rv = set_difference_untracked (so , other );
21912202 Py_END_CRITICAL_SECTION2 ();
2203+ if (rv != NULL ) {
2204+ _PyObject_GC_TRACK (rv );
2205+ }
21922206 return rv ;
21932207}
21942208
0 commit comments