@@ -1247,6 +1247,21 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
12471247 }
12481248}
12491249
1250+ static PyObject *
1251+ set_copy_untracked_lock_held (PySetObject * so )
1252+ {
1253+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (so );
1254+ PyObject * copy = make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
1255+ if (copy == NULL ) {
1256+ return NULL ;
1257+ }
1258+ if (set_merge_lock_held ((PySetObject * )copy , (PyObject * )so ) < 0 ) {
1259+ Py_DECREF (copy );
1260+ return NULL ;
1261+ }
1262+ return copy ;
1263+ }
1264+
12501265/*[clinic input]
12511266@critical_section
12521267set.copy
@@ -1259,14 +1274,9 @@ static PyObject *
12591274set_copy_impl (PySetObject * so )
12601275/*[clinic end generated code: output=c9223a1e1cc6b041 input=c169a4fbb8209257]*/
12611276{
1262- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (so );
1263- PyObject * copy = make_new_set_basetype (Py_TYPE (so ), NULL );
1264- if (copy == NULL ) {
1265- return NULL ;
1266- }
1267- if (set_merge_lock_held ((PySetObject * )copy , (PyObject * )so ) < 0 ) {
1268- Py_DECREF (copy );
1269- return NULL ;
1277+ PyObject * copy = set_copy_untracked_lock_held (so );
1278+ if (copy != NULL ) {
1279+ _PyObject_GC_TRACK (copy );
12701280 }
12711281 return copy ;
12721282}
@@ -1321,7 +1331,8 @@ set_union_impl(PySetObject *so, PyObject *args)
13211331 PyObject * other ;
13221332 Py_ssize_t i ;
13231333
1324- result = (PySetObject * )set_copy (so , NULL );
1334+ result = (PySetObject * )make_new_set_basetype_untracked (Py_TYPE (so ),
1335+ (PyObject * )so );
13251336 if (result == NULL )
13261337 return NULL ;
13271338
@@ -1334,6 +1345,7 @@ set_union_impl(PySetObject *so, PyObject *args)
13341345 return NULL ;
13351346 }
13361347 }
1348+ _PyObject_GC_TRACK (result );
13371349 return (PyObject * )result ;
13381350}
13391351
@@ -1718,11 +1730,11 @@ set_difference_update_impl(PySetObject *so, PyObject *args)
17181730}
17191731
17201732static PyObject *
1721- set_copy_and_difference (PySetObject * so , PyObject * other )
1733+ set_copy_and_difference_untracked (PySetObject * so , PyObject * other )
17221734{
17231735 PyObject * result ;
17241736
1725- result = set_copy_impl (so );
1737+ result = set_copy_untracked_lock_held (so );
17261738 if (result == NULL )
17271739 return NULL ;
17281740 if (set_difference_update_internal ((PySetObject * ) result , other ) == 0 )
@@ -1732,7 +1744,7 @@ set_copy_and_difference(PySetObject *so, PyObject *other)
17321744}
17331745
17341746static PyObject *
1735- set_difference (PySetObject * so , PyObject * other )
1747+ set_difference_untracked (PySetObject * so , PyObject * other )
17361748{
17371749 PyObject * result ;
17381750 PyObject * key ;
@@ -1748,13 +1760,13 @@ set_difference(PySetObject *so, PyObject *other)
17481760 other_size = PyDict_GET_SIZE (other );
17491761 }
17501762 else {
1751- return set_copy_and_difference (so , other );
1763+ return set_copy_and_difference_untracked (so , other );
17521764 }
17531765
17541766 /* If len(so) much more than len(other), it's more efficient to simply copy
17551767 * so and then iterate other looking for common elements. */
17561768 if ((PySet_GET_SIZE (so ) >> 2 ) > other_size ) {
1757- return set_copy_and_difference (so , other );
1769+ return set_copy_and_difference_untracked (so , other );
17581770 }
17591771
17601772 result = make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
@@ -1781,7 +1793,6 @@ set_difference(PySetObject *so, PyObject *other)
17811793 }
17821794 Py_DECREF (key );
17831795 }
1784- _PyObject_GC_TRACK (result );
17851796 return result ;
17861797 }
17871798
@@ -1805,7 +1816,6 @@ set_difference(PySetObject *so, PyObject *other)
18051816 }
18061817 Py_DECREF (key );
18071818 }
1808- _PyObject_GC_TRACK (result );
18091819 return result ;
18101820}
18111821
@@ -1830,7 +1840,7 @@ set_difference_multi_impl(PySetObject *so, PyObject *args)
18301840
18311841 other = PyTuple_GET_ITEM (args , 0 );
18321842 Py_BEGIN_CRITICAL_SECTION2 (so , other );
1833- result = set_difference (so , other );
1843+ result = set_difference_untracked (so , other );
18341844 Py_END_CRITICAL_SECTION2 ();
18351845 if (result == NULL )
18361846 return NULL ;
@@ -1846,6 +1856,7 @@ set_difference_multi_impl(PySetObject *so, PyObject *args)
18461856 return NULL ;
18471857 }
18481858 }
1859+ _PyObject_GC_TRACK (result );
18491860 return result ;
18501861}
18511862
@@ -1857,8 +1868,11 @@ set_sub(PySetObject *so, PyObject *other)
18571868
18581869 PyObject * rv ;
18591870 Py_BEGIN_CRITICAL_SECTION2 (so , other );
1860- rv = set_difference (so , other );
1871+ rv = set_difference_untracked (so , other );
18611872 Py_END_CRITICAL_SECTION2 ();
1873+ if (rv != NULL ) {
1874+ _PyObject_GC_TRACK (rv );
1875+ }
18621876 return rv ;
18631877}
18641878
0 commit comments