]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-147985: Use lock-free lookup in `PySet_Contains` (#147986)
authorNeil Schemenauer <nas-github@arctrix.com>
Fri, 3 Apr 2026 06:34:06 +0000 (23:34 -0700)
committerGitHub <noreply@github.com>
Fri, 3 Apr 2026 06:34:06 +0000 (12:04 +0530)
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
Misc/NEWS.d/next/Core_and_Builtins/2026-04-01-12-35-55.gh-issue-147985.YVirHJ.rst [new file with mode: 0644]
Objects/setobject.c

diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-01-12-35-55.gh-issue-147985.YVirHJ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-01-12-35-55.gh-issue-147985.YVirHJ.rst
new file mode 100644 (file)
index 0000000..a94dfca
--- /dev/null
@@ -0,0 +1,3 @@
+Make :c:func:`PySet_Contains` attempt a lock-free lookup, similar to
+:meth:`!set.__contains__`.  This avoids acquiring the set object mutex in the
+normal case.
index ae6c1d1248d2fc9e8076ef3b2961d21d200bbc6d..1e63056360455296f46b99623c5725a18c516ed1 100644 (file)
@@ -3023,14 +3023,14 @@ PySet_Contains(PyObject *anyset, PyObject *key)
         PyErr_BadInternalCall();
         return -1;
     }
-    if (PyFrozenSet_CheckExact(anyset)) {
-        return set_contains_key((PySetObject *)anyset, key);
+
+    PySetObject *so = (PySetObject *)anyset;
+    Py_hash_t hash = _PyObject_HashFast(key);
+    if (hash == -1) {
+        set_unhashable_type(key);
+        return -1;
     }
-    int rv;
-    Py_BEGIN_CRITICAL_SECTION(anyset);
-    rv = set_contains_key((PySetObject *)anyset, key);
-    Py_END_CRITICAL_SECTION();
-    return rv;
+    return set_contains_entry(so, key, hash);
 }
 
 int