Skip to content

Commit 561df1e

Browse files
committed
gh-108732: include comprehension locals in frame.f_locals
1 parent bf414b7 commit 561df1e

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

Lib/test/test_listcomps.py

Lines changed: 7 additions & 0 deletions
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

Objects/frameobject.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,16 @@ static PyMemberDef frame_memberlist[] = {
2525
static PyObject *
2626
frame_getlocals(PyFrameObject *f, void *closure)
2727
{
28-
if (PyFrame_FastToLocalsWithError(f) < 0)
29-
return NULL;
30-
PyObject *locals = f->f_frame->f_locals;
31-
return Py_NewRef(locals);
28+
if (f == NULL) {
29+
PyErr_BadInternalCall();
30+
return -1;
31+
}
32+
assert(!_PyFrame_IsIncomplete(f->f_frame));
33+
PyObject *locals = _PyFrame_GetLocals(f->f_frame, 1);
34+
if (locals) {
35+
f->f_fast_as_locals = 1;
36+
}
37+
return locals;
3238
}
3339

3440
int
@@ -1342,11 +1348,11 @@ PyFrame_GetVarString(PyFrameObject *frame, const char *name)
13421348
int
13431349
PyFrame_FastToLocalsWithError(PyFrameObject *f)
13441350
{
1345-
assert(!_PyFrame_IsIncomplete(f->f_frame));
13461351
if (f == NULL) {
13471352
PyErr_BadInternalCall();
13481353
return -1;
13491354
}
1355+
assert(!_PyFrame_IsIncomplete(f->f_frame));
13501356
int err = _PyFrame_FastToLocalsWithError(f->f_frame);
13511357
if (err == 0) {
13521358
f->f_fast_as_locals = 1;

0 commit comments

Comments
 (0)