]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-128396: Fix a crash when inline comprehension has the same … (#130311)
authorTian Gao <gaogaotiantian@hotmail.com>
Wed, 19 Feb 2025 17:40:03 +0000 (12:40 -0500)
committerGitHub <noreply@github.com>
Wed, 19 Feb 2025 17:40:03 +0000 (17:40 +0000)
[3.13] gh-128396: Fix a crash when inline comprehension has the same local variable as the outside scope (GH-130235)
(cherry picked from commit ccf17323c218a2fdcf7f4845d3eaa74ebddefa44)

Lib/test/test_frame.py
Misc/NEWS.d/next/Core and Builtins/2025-02-17-18-59-33.gh-issue-128396.iVtoYY.rst [new file with mode: 0644]
Objects/frameobject.c

index 26100fe6e8421a6099b99cbe2166ae91d398e2b1..2f802179cb3f58503d9fc926d36cae41e0d4ea35 100644 (file)
@@ -298,6 +298,12 @@ class TestFrameLocals(unittest.TestCase):
         self.assertEqual(x, 2)
         self.assertEqual(y, 3)
 
+    def test_closure_with_inline_comprehension(self):
+        lambda: k
+        k = 1
+        lst = [locals() for k in [0]]
+        self.assertEqual(lst[0]['k'], 0)
+
     def test_as_dict(self):
         x = 1
         y = 2
diff --git a/Misc/NEWS.d/next/Core and Builtins/2025-02-17-18-59-33.gh-issue-128396.iVtoYY.rst b/Misc/NEWS.d/next/Core and Builtins/2025-02-17-18-59-33.gh-issue-128396.iVtoYY.rst
new file mode 100644 (file)
index 0000000..4382b77
--- /dev/null
@@ -0,0 +1 @@
+Fix a crash that occurs when calling :func:`locals` inside an inline comprehension that uses the same local variable as the outer frame scope where the variable is a free or cell var.
index 8c596ede70ca3d861b9dc613c5b6718b253cb4a1..d947f655d573ba62721a629726a3addd03cdb335 100644 (file)
@@ -35,8 +35,15 @@ framelocalsproxy_getval(_PyInterpreterFrame *frame, PyCodeObject *co, int i)
     if (kind == CO_FAST_FREE || kind & CO_FAST_CELL) {
         // The cell was set when the frame was created from
         // the function's closure.
-        assert(PyCell_Check(value));
-        cell = value;
+        // GH-128396: With PEP 709, it's possible to have a fast variable in
+        // an inlined comprehension that has the same name as the cell variable
+        // in the frame, where the `kind` obtained from frame can not guarantee
+        // that the variable is a cell.
+        // If the variable is not a cell, we are okay with it and we can simply
+        // return the value.
+        if (PyCell_Check(value)) {
+            cell = value;
+        }
     }
 
     if (cell != NULL) {