https://github.com/python/cpython/commit/cc00fe4cb2d0e202a8a1e6bfccfec1fcfe3d76df commit: cc00fe4cb2d0e202a8a1e6bfccfec1fcfe3d76df branch: 3.15 author: Miss Islington (bot) <[email protected]> committer: methane <[email protected]> date: 2026-10-13T17:12:31+09:00 summary:
gh-159285: Fix crash when copying an empty dict fails with MemoryError (GH-159286) copy_lock_held_untracked() asserted that the new empty dict was not tracked by the GC without checking whether its allocation had failed, so a debug build dereferenced NULL instead of raising MemoryError. This affected dict.copy(), PyDict_Copy() and _PyDict_CopyAsDict(), which type() uses for the class namespace. (cherry picked from commit f9132f1c555f0e47d7e38251f96adaf0355f9c08) Co-authored-by: Christian Aurich Zanettini Martins <[email protected]> files: A Misc/NEWS.d/next/Core_and_Builtins/2026-10-12-23-32-50.gh-issue-159285.nlLuwQ.rst M Lib/test/test_dict.py M Objects/dictobject.c diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 3b9ff672a1aa03..4fc851c0ce464b 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -459,6 +459,18 @@ def test_copy_noncompact(self): d2 = d.copy() self.assertEqual(d2, d) + @support.nomemtest + def test_copy_empty_no_memory(self): + import _testcapi + d = {} + d_copy = d.copy + with self.assertRaises(MemoryError): + try: + _testcapi.set_nomemory(0) + d_copy() + finally: + _testcapi.remove_mem_hooks() + def test_get(self): d = {} self.assertIs(d.get('c'), None) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-12-23-32-50.gh-issue-159285.nlLuwQ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-12-23-32-50.gh-issue-159285.nlLuwQ.rst new file mode 100644 index 00000000000000..0cb795f8309f73 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-12-23-32-50.gh-issue-159285.nlLuwQ.rst @@ -0,0 +1,2 @@ +Fix a crash in a debug build when copying an empty :class:`dict` fails with +:exc:`MemoryError`. Patch by Christian Aurich Zanettini Martins. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index e900ef33cc42f5..89b4abd596761c 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4448,7 +4448,7 @@ copy_lock_held_untracked(PyObject *o, int as_frozendict) else { d = dict_new_untracked(&PyDict_Type); } - assert(!_PyObject_GC_IS_TRACKED(d)); + assert(d == NULL || !_PyObject_GC_IS_TRACKED(d)); return d; } _______________________________________________ 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]
