diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2023-09-12 13:50:29 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-12 13:50:29 (GMT) |
commit | d533ab17ec37b457a5cc286f30c7559e358492bf (patch) | |
tree | 2260c776dd98ec4e61519099c2b82169fdabe092 | |
parent | af83d1e8214efc806488226d206c24462686bd1d (diff) | |
download | cpython-d533ab17ec37b457a5cc286f30c7559e358492bf.zip cpython-d533ab17ec37b457a5cc286f30c7559e358492bf.tar.gz cpython-d533ab17ec37b457a5cc286f30c7559e358492bf.tar.bz2 |
[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 f2584eade378910b9ea18072bb1dab3dd58e23bb)
Co-authored-by: Carl Meyer <carl@oddbird.net>
Co-authored-by: Radislav Chugunov <52372310+chgnrdv@users.noreply.github.com>
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
-rw-r--r-- | Lib/test/test_listcomps.py | 7 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst | 2 | ||||
-rw-r--r-- | Objects/frameobject.c | 14 |
3 files changed, 19 insertions, 4 deletions
diff --git a/Lib/test/test_listcomps.py b/Lib/test/test_listcomps.py index bedd99b..c108957 100644 --- a/Lib/test/test_listcomps.py +++ b/Lib/test/test_listcomps.py @@ -596,6 +596,13 @@ class ListComprehensionTest(unittest.TestCase): """ 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} diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst new file mode 100644 index 0000000..94a143b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst @@ -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. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index ba36575..30c8d3c 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -24,10 +24,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 @@ -1351,11 +1357,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; |