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]

Reply via email to