Skip to content

Commit

Permalink
pythongh-108732: include comprehension locals in frame.f_locals (pyth…
Browse files Browse the repository at this point in the history
…on#109026)

Co-authored-by: Radislav Chugunov <[email protected]>
Co-authored-by: Jelle Zijlstra <[email protected]>
  • Loading branch information
3 people authored Sep 7, 2023
1 parent b72251d commit f2584ea
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
7 changes: 7 additions & 0 deletions Lib/test/test_listcomps.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,13 @@ def test_exception_in_post_comp_call(self):
"""
self._check_in_scopes(code, {"value": [1, None]})

def test_frame_locals(self):
code = """
val = [sys._getframe().f_locals for a in [0]][0]["a"]
"""
import sys
self._check_in_scopes(code, {"val": 0}, ns={"sys": sys})


__test__ = {'doctests' : doctests}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Make iteration variables of module- and class-scoped comprehensions visible
to pdb and other tools that use ``frame.f_locals`` again.
14 changes: 10 additions & 4 deletions Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ static PyMemberDef frame_memberlist[] = {
static PyObject *
frame_getlocals(PyFrameObject *f, void *closure)
{
if (PyFrame_FastToLocalsWithError(f) < 0)
if (f == NULL) {
PyErr_BadInternalCall();
return NULL;
PyObject *locals = f->f_frame->f_locals;
return Py_NewRef(locals);
}
assert(!_PyFrame_IsIncomplete(f->f_frame));
PyObject *locals = _PyFrame_GetLocals(f->f_frame, 1);
if (locals) {
f->f_fast_as_locals = 1;
}
return locals;
}

int
Expand Down Expand Up @@ -1342,11 +1348,11 @@ PyFrame_GetVarString(PyFrameObject *frame, const char *name)
int
PyFrame_FastToLocalsWithError(PyFrameObject *f)
{
assert(!_PyFrame_IsIncomplete(f->f_frame));
if (f == NULL) {
PyErr_BadInternalCall();
return -1;
}
assert(!_PyFrame_IsIncomplete(f->f_frame));
int err = _PyFrame_FastToLocalsWithError(f->f_frame);
if (err == 0) {
f->f_fast_as_locals = 1;
Expand Down

0 comments on commit f2584ea

Please sign in to comment.