Skip to content

Commit d533ab1

Browse files
miss-islingtoncarljmchgnrdvJelleZijlstra
authored
[3.12] gh-108732: include comprehension locals in frame.f_locals (GH-109026) (#109097)
gh-108732: include comprehension locals in frame.f_locals (GH-109026) (cherry picked from commit f2584ea) Co-authored-by: Carl Meyer <[email protected]> Co-authored-by: Radislav Chugunov <[email protected]> Co-authored-by: Jelle Zijlstra <[email protected]>
1 parent af83d1e commit d533ab1

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

Lib/test/test_listcomps.py

+7
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,13 @@ def test_exception_in_post_comp_call(self):
596596
"""
597597
self._check_in_scopes(code, {"value": [1, None]})
598598

599+
def test_frame_locals(self):
600+
code = """
601+
val = [sys._getframe().f_locals for a in [0]][0]["a"]
602+
"""
603+
import sys
604+
self._check_in_scopes(code, {"val": 0}, ns={"sys": sys})
605+
599606

600607
__test__ = {'doctests' : doctests}
601608

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Make iteration variables of module- and class-scoped comprehensions visible
2+
to pdb and other tools that use ``frame.f_locals`` again.

Objects/frameobject.c

+10-4
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@ static PyMemberDef frame_memberlist[] = {
2424
static PyObject *
2525
frame_getlocals(PyFrameObject *f, void *closure)
2626
{
27-
if (PyFrame_FastToLocalsWithError(f) < 0)
27+
if (f == NULL) {
28+
PyErr_BadInternalCall();
2829
return NULL;
29-
PyObject *locals = f->f_frame->f_locals;
30-
return Py_NewRef(locals);
30+
}
31+
assert(!_PyFrame_IsIncomplete(f->f_frame));
32+
PyObject *locals = _PyFrame_GetLocals(f->f_frame, 1);
33+
if (locals) {
34+
f->f_fast_as_locals = 1;
35+
}
36+
return locals;
3137
}
3238

3339
int
@@ -1351,11 +1357,11 @@ PyFrame_GetVarString(PyFrameObject *frame, const char *name)
13511357
int
13521358
PyFrame_FastToLocalsWithError(PyFrameObject *f)
13531359
{
1354-
assert(!_PyFrame_IsIncomplete(f->f_frame));
13551360
if (f == NULL) {
13561361
PyErr_BadInternalCall();
13571362
return -1;
13581363
}
1364+
assert(!_PyFrame_IsIncomplete(f->f_frame));
13591365
int err = _PyFrame_FastToLocalsWithError(f->f_frame);
13601366
if (err == 0) {
13611367
f->f_fast_as_locals = 1;

0 commit comments

Comments
 (0)