diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-01-00-00-00.gh-issue-158525.Xw3K9a.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-01-00-00-00.gh-issue-158525.Xw3K9a.rst new file mode 100644 index 00000000000000..43e5bcbf1817b0 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-01-00-00-00.gh-issue-158525.Xw3K9a.rst @@ -0,0 +1,2 @@ +Avoid reacquiring the source dictionary lock when copying a sparse dictionary +in the free-threaded build. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 15377ac083c2b2..d57f63512df832 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4575,7 +4575,14 @@ copy_lock_held_untracked(PyObject *o, int as_frozendict) } if (copy == NULL) return NULL; - if (dict_merge(copy, o, 1, NULL) < 0) { + int res; + if (!PyFrozenDict_Check(o) && Py_TYPE(mp)->tp_iter == dict_iter) { + res = dict_dict_merge((PyDictObject *)copy, mp, 1, NULL); + } + else { + res = dict_merge(copy, o, 1, NULL); + } + if (res < 0) { Py_DECREF(copy); return NULL; }