From 399ee26ed56d1dd1dc490651b60c6e811a1720ac Mon Sep 17 00:00:00 2001 From: Neil Schemenauer Date: Wed, 1 Apr 2026 12:32:40 -0700 Subject: [PATCH 1/2] Use lock-free lookup in PySet_Contains(). --- .../2026-04-01-12-35-55.gh-issue-147985.YVirHJ.rst | 3 +++ Objects/setobject.c | 14 +++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-04-01-12-35-55.gh-issue-147985.YVirHJ.rst 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 index 00000000000000..1a7dab2141d131 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-01-12-35-55.gh-issue-147985.YVirHJ.rst @@ -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. diff --git a/Objects/setobject.c b/Objects/setobject.c index ae6c1d1248d2fc..1e630563604552 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -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 From 988e4974bcf68d05d186043a752a3227b8a3cf5f Mon Sep 17 00:00:00 2001 From: Neil Schemenauer Date: Wed, 1 Apr 2026 22:43:18 -0700 Subject: [PATCH 2/2] Fix markup in blurb. Co-authored-by: Kumar Aditya --- .../2026-04-01-12-35-55.gh-issue-147985.YVirHJ.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 1a7dab2141d131..a94dfca5e2a498 100644 --- 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 @@ -1,3 +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 +:meth:`!set.__contains__`. This avoids acquiring the set object mutex in the normal case.