@@ -1577,6 +1577,21 @@ _PySet_Freeze(PyObject *set)
15771577 return Py_NewRef (set );
15781578}
15791579
1580+ static PyObject *
1581+ set_copy_untracked_lock_held (PySetObject * so )
1582+ {
1583+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (so );
1584+ PyObject * copy = make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
1585+ if (copy == NULL ) {
1586+ return NULL ;
1587+ }
1588+ if (set_merge_lock_held ((PySetObject * )copy , (PyObject * )so ) < 0 ) {
1589+ Py_DECREF (copy );
1590+ return NULL ;
1591+ }
1592+ return copy ;
1593+ }
1594+
15801595/*[clinic input]
15811596@critical_section
15821597set.copy
@@ -1589,14 +1604,9 @@ static PyObject *
15891604set_copy_impl (PySetObject * so )
15901605/*[clinic end generated code: output=c9223a1e1cc6b041 input=c169a4fbb8209257]*/
15911606{
1592- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (so );
1593- PyObject * copy = make_new_set_basetype (Py_TYPE (so ), NULL );
1594- if (copy == NULL ) {
1595- return NULL ;
1596- }
1597- if (set_merge_lock_held ((PySetObject * )copy , (PyObject * )so ) < 0 ) {
1598- Py_DECREF (copy );
1599- return NULL ;
1607+ PyObject * copy = set_copy_untracked_lock_held (so );
1608+ if (copy != NULL ) {
1609+ _PyObject_GC_TRACK (copy );
16001610 }
16011611 return copy ;
16021612}
@@ -1652,7 +1662,8 @@ set_union_impl(PySetObject *so, PyObject * const *others,
16521662 PyObject * other ;
16531663 Py_ssize_t i ;
16541664
1655- result = (PySetObject * )set_copy ((PyObject * )so , NULL );
1665+ result = (PySetObject * )make_new_set_basetype_untracked (Py_TYPE (so ),
1666+ (PyObject * )so );
16561667 if (result == NULL )
16571668 return NULL ;
16581669
@@ -1665,6 +1676,7 @@ set_union_impl(PySetObject *so, PyObject * const *others,
16651676 return NULL ;
16661677 }
16671678 }
1679+ _PyObject_GC_TRACK (result );
16681680 return (PyObject * )result ;
16691681}
16701682
@@ -2055,11 +2067,11 @@ set_difference_update_impl(PySetObject *so, PyObject * const *others,
20552067}
20562068
20572069static PyObject *
2058- set_copy_and_difference (PySetObject * so , PyObject * other )
2070+ set_copy_and_difference_untracked (PySetObject * so , PyObject * other )
20592071{
20602072 PyObject * result ;
20612073
2062- result = set_copy_impl (so );
2074+ result = set_copy_untracked_lock_held (so );
20632075 if (result == NULL )
20642076 return NULL ;
20652077 if (set_difference_update_internal ((PySetObject * ) result , other ) == 0 )
@@ -2069,7 +2081,7 @@ set_copy_and_difference(PySetObject *so, PyObject *other)
20692081}
20702082
20712083static PyObject *
2072- set_difference (PySetObject * so , PyObject * other )
2084+ set_difference_untracked (PySetObject * so , PyObject * other )
20732085{
20742086 PyObject * result ;
20752087 PyObject * key ;
@@ -2085,13 +2097,13 @@ set_difference(PySetObject *so, PyObject *other)
20852097 other_size = PyDict_GET_SIZE (other );
20862098 }
20872099 else {
2088- return set_copy_and_difference (so , other );
2100+ return set_copy_and_difference_untracked (so , other );
20892101 }
20902102
20912103 /* If len(so) much more than len(other), it's more efficient to simply copy
20922104 * so and then iterate other looking for common elements. */
20932105 if ((PySet_GET_SIZE (so ) >> 2 ) > other_size ) {
2094- return set_copy_and_difference (so , other );
2106+ return set_copy_and_difference_untracked (so , other );
20952107 }
20962108
20972109 result = make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
@@ -2118,7 +2130,6 @@ set_difference(PySetObject *so, PyObject *other)
21182130 }
21192131 Py_DECREF (key );
21202132 }
2121- _PyObject_GC_TRACK (result );
21222133 return result ;
21232134 }
21242135
@@ -2142,7 +2153,6 @@ set_difference(PySetObject *so, PyObject *other)
21422153 }
21432154 Py_DECREF (key );
21442155 }
2145- _PyObject_GC_TRACK (result );
21462156 return result ;
21472157}
21482158
@@ -2169,7 +2179,7 @@ set_difference_multi_impl(PySetObject *so, PyObject * const *others,
21692179
21702180 other = others [0 ];
21712181 Py_BEGIN_CRITICAL_SECTION2 (so , other );
2172- result = set_difference (so , other );
2182+ result = set_difference_untracked (so , other );
21732183 Py_END_CRITICAL_SECTION2 ();
21742184 if (result == NULL )
21752185 return NULL ;
@@ -2185,6 +2195,7 @@ set_difference_multi_impl(PySetObject *so, PyObject * const *others,
21852195 return NULL ;
21862196 }
21872197 }
2198+ _PyObject_GC_TRACK (result );
21882199 return result ;
21892200}
21902201
@@ -2197,8 +2208,11 @@ set_sub(PyObject *self, PyObject *other)
21972208
21982209 PyObject * rv ;
21992210 Py_BEGIN_CRITICAL_SECTION2 (so , other );
2200- rv = set_difference (so , other );
2211+ rv = set_difference_untracked (so , other );
22012212 Py_END_CRITICAL_SECTION2 ();
2213+ if (rv != NULL ) {
2214+ _PyObject_GC_TRACK (rv );
2215+ }
22022216 return rv ;
22032217}
22042218
0 commit comments