@@ -1304,6 +1304,21 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
13041304 }
13051305}
13061306
1307+ static PyObject *
1308+ set_copy_untracked_lock_held (PySetObject * so )
1309+ {
1310+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (so );
1311+ PyObject * copy = make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
1312+ if (copy == NULL ) {
1313+ return NULL ;
1314+ }
1315+ if (set_merge_lock_held ((PySetObject * )copy , (PyObject * )so ) < 0 ) {
1316+ Py_DECREF (copy );
1317+ return NULL ;
1318+ }
1319+ return copy ;
1320+ }
1321+
13071322/*[clinic input]
13081323@critical_section
13091324set.copy
@@ -1316,14 +1331,9 @@ static PyObject *
13161331set_copy_impl (PySetObject * so )
13171332/*[clinic end generated code: output=c9223a1e1cc6b041 input=c169a4fbb8209257]*/
13181333{
1319- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (so );
1320- PyObject * copy = make_new_set_basetype (Py_TYPE (so ), NULL );
1321- if (copy == NULL ) {
1322- return NULL ;
1323- }
1324- if (set_merge_lock_held ((PySetObject * )copy , (PyObject * )so ) < 0 ) {
1325- Py_DECREF (copy );
1326- return NULL ;
1334+ PyObject * copy = set_copy_untracked_lock_held (so );
1335+ if (copy != NULL ) {
1336+ _PyObject_GC_TRACK (copy );
13271337 }
13281338 return copy ;
13291339}
@@ -1379,7 +1389,8 @@ set_union_impl(PySetObject *so, PyObject * const *others,
13791389 PyObject * other ;
13801390 Py_ssize_t i ;
13811391
1382- result = (PySetObject * )set_copy ((PyObject * )so , NULL );
1392+ result = (PySetObject * )make_new_set_basetype_untracked (Py_TYPE (so ),
1393+ (PyObject * )so );
13831394 if (result == NULL )
13841395 return NULL ;
13851396
@@ -1392,6 +1403,7 @@ set_union_impl(PySetObject *so, PyObject * const *others,
13921403 return NULL ;
13931404 }
13941405 }
1406+ _PyObject_GC_TRACK (result );
13951407 return (PyObject * )result ;
13961408}
13971409
@@ -1782,11 +1794,11 @@ set_difference_update_impl(PySetObject *so, PyObject * const *others,
17821794}
17831795
17841796static PyObject *
1785- set_copy_and_difference (PySetObject * so , PyObject * other )
1797+ set_copy_and_difference_untracked (PySetObject * so , PyObject * other )
17861798{
17871799 PyObject * result ;
17881800
1789- result = set_copy_impl (so );
1801+ result = set_copy_untracked_lock_held (so );
17901802 if (result == NULL )
17911803 return NULL ;
17921804 if (set_difference_update_internal ((PySetObject * ) result , other ) == 0 )
@@ -1796,7 +1808,7 @@ set_copy_and_difference(PySetObject *so, PyObject *other)
17961808}
17971809
17981810static PyObject *
1799- set_difference (PySetObject * so , PyObject * other )
1811+ set_difference_untracked (PySetObject * so , PyObject * other )
18001812{
18011813 PyObject * result ;
18021814 PyObject * key ;
@@ -1812,13 +1824,13 @@ set_difference(PySetObject *so, PyObject *other)
18121824 other_size = PyDict_GET_SIZE (other );
18131825 }
18141826 else {
1815- return set_copy_and_difference (so , other );
1827+ return set_copy_and_difference_untracked (so , other );
18161828 }
18171829
18181830 /* If len(so) much more than len(other), it's more efficient to simply copy
18191831 * so and then iterate other looking for common elements. */
18201832 if ((PySet_GET_SIZE (so ) >> 2 ) > other_size ) {
1821- return set_copy_and_difference (so , other );
1833+ return set_copy_and_difference_untracked (so , other );
18221834 }
18231835
18241836 result = make_new_set_basetype_untracked (Py_TYPE (so ), NULL );
@@ -1845,7 +1857,6 @@ set_difference(PySetObject *so, PyObject *other)
18451857 }
18461858 Py_DECREF (key );
18471859 }
1848- _PyObject_GC_TRACK (result );
18491860 return result ;
18501861 }
18511862
@@ -1869,7 +1880,6 @@ set_difference(PySetObject *so, PyObject *other)
18691880 }
18701881 Py_DECREF (key );
18711882 }
1872- _PyObject_GC_TRACK (result );
18731883 return result ;
18741884}
18751885
@@ -1895,7 +1905,7 @@ set_difference_multi_impl(PySetObject *so, PyObject * const *others,
18951905
18961906 other = others [0 ];
18971907 Py_BEGIN_CRITICAL_SECTION2 (so , other );
1898- result = set_difference (so , other );
1908+ result = set_difference_untracked (so , other );
18991909 Py_END_CRITICAL_SECTION2 ();
19001910 if (result == NULL )
19011911 return NULL ;
@@ -1911,6 +1921,7 @@ set_difference_multi_impl(PySetObject *so, PyObject * const *others,
19111921 return NULL ;
19121922 }
19131923 }
1924+ _PyObject_GC_TRACK (result );
19141925 return result ;
19151926}
19161927
@@ -1923,8 +1934,11 @@ set_sub(PyObject *self, PyObject *other)
19231934
19241935 PyObject * rv ;
19251936 Py_BEGIN_CRITICAL_SECTION2 (so , other );
1926- rv = set_difference (so , other );
1937+ rv = set_difference_untracked (so , other );
19271938 Py_END_CRITICAL_SECTION2 ();
1939+ if (rv != NULL ) {
1940+ _PyObject_GC_TRACK (rv );
1941+ }
19281942 return rv ;
19291943}
19301944
0 commit comments