From 8976129dd2bf0d21493a4e22c067059916b066d2 Mon Sep 17 00:00:00 2001 From: Brij <97006829+brijkapadia@users.noreply.github.com> Date: Fri, 17 Jul 2026 22:04:15 -0400 Subject: [PATCH 1/3] gh-153881: Atomically load `dk_nentries` in `_PyObject_IsInstanceDictEmpty` --- Lib/test/test_free_threading/test_dict.py | 20 +++++++++++++++++++ ...-07-17-22-03-39.gh-issue-153881.oDa06s.rst | 1 + Objects/dictobject.c | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst diff --git a/Lib/test/test_free_threading/test_dict.py b/Lib/test/test_free_threading/test_dict.py index ad23290a92ab345..4a812275143bc4d 100644 --- a/Lib/test/test_free_threading/test_dict.py +++ b/Lib/test/test_free_threading/test_dict.py @@ -336,5 +336,25 @@ def reader(): with threading_helper.start_threads([t1, t2]): pass + def test_getstate_race_with_shared_keys(self): + box = [None] + enter = Barrier(2) + leave = Barrier(2) + + def reader(): + for _ in range(1000): + enter.wait() + box[0].__getstate__() + leave.wait() + + def writer(): + for i in range(1000): + box[0] = type(f"C{i}", (), {})() + enter.wait() + setattr(box[0], str(i), 1) + leave.wait() + + threading_helper.run_concurrently([reader, writer]) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst new file mode 100644 index 000000000000000..4f4418e4605416f --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst @@ -0,0 +1 @@ +Fix potential data race when calling :meth:`object.__getstate__`. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 246ffe6c18e9b51..c650aa456d2cc9d 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -7722,7 +7722,7 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) PyDictValues *values = _PyObject_InlineValues(obj); if (FT_ATOMIC_LOAD_UINT8(values->valid)) { PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + for (Py_ssize_t i = 0; i < LOAD_KEYS_NENTRIES(keys); i++) { if (FT_ATOMIC_LOAD_PTR_RELAXED(values->values[i]) != NULL) { return 0; } From 89a09c3073ea2c95d0dab8aaf3654f7214960429 Mon Sep 17 00:00:00 2001 From: Brij <97006829+brijkapadia@users.noreply.github.com> Date: Sat, 18 Jul 2026 06:12:59 -0400 Subject: [PATCH 2/3] Update NEWS --- .../2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst index 4f4418e4605416f..72d07f3b62417b6 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst @@ -1 +1,2 @@ -Fix potential data race when calling :meth:`object.__getstate__`. +Fix potential data race when calling :meth:`object.__getstate__` +under the :term:`free-threaded build`. From 9c26ed25b1b5cde4c29bd525337e84033c546499 Mon Sep 17 00:00:00 2001 From: Brij <97006829+brijkapadia@users.noreply.github.com> Date: Sat, 18 Jul 2026 09:57:37 -0400 Subject: [PATCH 3/3] small change --- .../2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst index 72d07f3b62417b6..8facf88367fda7f 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-17-22-03-39.gh-issue-153881.oDa06s.rst @@ -1,2 +1,2 @@ -Fix potential data race when calling :meth:`object.__getstate__` +Fix potential data race when calling :meth:`~object.__getstate__` under the :term:`free-threaded build`.