File tree
Lib/test
Misc/NEWS.d/next/Core_and_Builtins
Objects
Original file line numberDiff line numberDiff line change@@ -346,6 +346,12 @@ def f():
346346self.assertEqual(x, 2)
347347self.assertEqual(y, 3)
348348349+deftest_closure_with_inline_comprehension(self):
350+lambda: k
351+k=1
352+lst= [locals() forkin [0]]
353+self.assertEqual(lst[0]['k'], 0)
354+349355deftest_as_dict(self):
350356x=1
351357y=2
Original file line numberDiff line numberDiff line change@@ -0,0 +1 @@
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.
Original file line numberDiff line numberDiff line change@@ -45,8 +45,15 @@ framelocalsproxy_getval(_PyInterpreterFrame *frame, PyCodeObject *co, int i)
4545if (kind==CO_FAST_FREE||kind&CO_FAST_CELL) {
4646// The cell was set when the frame was created from
4747// the function's closure.
48-assert(PyCell_Check(value));
49-cell=value;
48+// GH-128396: With PEP 709, it's possible to have a fast variable in
49+// an inlined comprehension that has the same name as the cell variable
50+// in the frame, where the `kind` obtained from frame can not guarantee
51+// that the variable is a cell.
52+// If the variable is not a cell, we are okay with it and we can simply
53+// return the value.
54+if (PyCell_Check(value)) {
55+cell=value;
56+ }
5057 }
51585259if (cell!=NULL) {