https://github.com/python/cpython/commit/073b658dd317ecdcab99898bca053aab59ea590d
commit: 073b658dd317ecdcab99898bca053aab59ea590d
branch: 3.15
author: Donghee Na <[email protected]>
committer: corona10 <[email protected]>
date: 2026-06-26T17:54:25Z
summary:
[3.15] gh-152235: Defer GC tracking in set.union and set.difference (gh-152290)
(gh-152316)
(cherry picked from commit 5a549e82b81378cb294904dab49cbee853bddd64)
files:
M
Misc/NEWS.d/next/Core_and_Builtins/2026-06-26-22-03-16.gh-issue-152235.ZKWiWk.rst
M Objects/setobject.c
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-26-22-03-16.gh-issue-152235.ZKWiWk.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-26-22-03-16.gh-issue-152235.ZKWiWk.rst
index bcc128404897da..ff89a2445cb4fe 100644
---
a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-26-22-03-16.gh-issue-152235.ZKWiWk.rst
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-26-22-03-16.gh-issue-152235.ZKWiWk.rst
@@ -1,2 +1,3 @@
-Defer GC tracking of :meth:`set.intersection`, :meth:`set.difference` and
-:meth:`set.symmetric_difference`. Patch by Donghee Na.
+Defer GC tracking of :meth:`set.intersection`, :meth:`set.difference`,
+:meth:`set.symmetric_difference`, :meth:`set.union` and ``set.__sub__``.
+Patch by Donghee Na.
diff --git a/Objects/setobject.c b/Objects/setobject.c
index aec73993451f65..bb407ceabadf1c 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -1567,6 +1567,21 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
FT_ATOMIC_STORE_PTR_RELEASE(b->table, b_table);
}
+static PyObject *
+set_copy_untracked_lock_held(PySetObject *so)
+{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
+ PyObject *copy = make_new_set_basetype_untracked(Py_TYPE(so), NULL);
+ if (copy == NULL) {
+ return NULL;
+ }
+ if (set_merge_lock_held((PySetObject *)copy, (PyObject *)so) < 0) {
+ Py_DECREF(copy);
+ return NULL;
+ }
+ return copy;
+}
+
/*[clinic input]
@critical_section
set.copy
@@ -1579,14 +1594,9 @@ static PyObject *
set_copy_impl(PySetObject *so)
/*[clinic end generated code: output=c9223a1e1cc6b041 input=c169a4fbb8209257]*/
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
- PyObject *copy = make_new_set_basetype(Py_TYPE(so), NULL);
- if (copy == NULL) {
- return NULL;
- }
- if (set_merge_lock_held((PySetObject *)copy, (PyObject *)so) < 0) {
- Py_DECREF(copy);
- return NULL;
+ PyObject *copy = set_copy_untracked_lock_held(so);
+ if (copy != NULL) {
+ _PyObject_GC_TRACK(copy);
}
return copy;
}
@@ -1642,7 +1652,8 @@ set_union_impl(PySetObject *so, PyObject * const *others,
PyObject *other;
Py_ssize_t i;
- result = (PySetObject *)set_copy((PyObject *)so, NULL);
+ result = (PySetObject *)make_new_set_basetype_untracked(Py_TYPE(so),
+ (PyObject *)so);
if (result == NULL)
return NULL;
@@ -1655,6 +1666,7 @@ set_union_impl(PySetObject *so, PyObject * const *others,
return NULL;
}
}
+ _PyObject_GC_TRACK(result);
return (PyObject *)result;
}
@@ -2045,11 +2057,11 @@ set_difference_update_impl(PySetObject *so, PyObject *
const *others,
}
static PyObject *
-set_copy_and_difference(PySetObject *so, PyObject *other)
+set_copy_and_difference_untracked(PySetObject *so, PyObject *other)
{
PyObject *result;
- result = set_copy_impl(so);
+ result = set_copy_untracked_lock_held(so);
if (result == NULL)
return NULL;
if (set_difference_update_internal((PySetObject *) result, other) == 0)
@@ -2059,7 +2071,7 @@ set_copy_and_difference(PySetObject *so, PyObject *other)
}
static PyObject *
-set_difference(PySetObject *so, PyObject *other)
+set_difference_untracked(PySetObject *so, PyObject *other)
{
PyObject *result;
PyObject *key;
@@ -2075,13 +2087,13 @@ set_difference(PySetObject *so, PyObject *other)
other_size = PyDict_GET_SIZE(other);
}
else {
- return set_copy_and_difference(so, other);
+ return set_copy_and_difference_untracked(so, other);
}
/* If len(so) much more than len(other), it's more efficient to simply copy
* so and then iterate other looking for common elements. */
if ((PySet_GET_SIZE(so) >> 2) > other_size) {
- return set_copy_and_difference(so, other);
+ return set_copy_and_difference_untracked(so, other);
}
result = make_new_set_basetype_untracked(Py_TYPE(so), NULL);
@@ -2108,7 +2120,6 @@ set_difference(PySetObject *so, PyObject *other)
}
Py_DECREF(key);
}
- _PyObject_GC_TRACK(result);
return result;
}
@@ -2132,7 +2143,6 @@ set_difference(PySetObject *so, PyObject *other)
}
Py_DECREF(key);
}
- _PyObject_GC_TRACK(result);
return result;
}
@@ -2159,7 +2169,7 @@ set_difference_multi_impl(PySetObject *so, PyObject *
const *others,
other = others[0];
Py_BEGIN_CRITICAL_SECTION2(so, other);
- result = set_difference(so, other);
+ result = set_difference_untracked(so, other);
Py_END_CRITICAL_SECTION2();
if (result == NULL)
return NULL;
@@ -2175,6 +2185,7 @@ set_difference_multi_impl(PySetObject *so, PyObject *
const *others,
return NULL;
}
}
+ _PyObject_GC_TRACK(result);
return result;
}
@@ -2187,8 +2198,11 @@ set_sub(PyObject *self, PyObject *other)
PyObject *rv;
Py_BEGIN_CRITICAL_SECTION2(so, other);
- rv = set_difference(so, other);
+ rv = set_difference_untracked(so, other);
Py_END_CRITICAL_SECTION2();
+ if (rv != NULL) {
+ _PyObject_GC_TRACK(rv);
+ }
return rv;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]