From 991c73c23c50ef9872ca28002addf88d07acd1c2 Mon Sep 17 00:00:00 2001 From: Carl Meyer Date: Wed, 6 Sep 2023 13:13:20 -0700 Subject: [PATCH 1/3] gh-108732: include comprehension locals in frame.f_locals --- Lib/test/test_listcomps.py | 7 +++++++ ...023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst | 2 ++ Objects/frameobject.c | 16 +++++++++++----- 3 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst diff --git a/Lib/test/test_listcomps.py b/Lib/test/test_listcomps.py index bedd99b4a44fcb..c1089574d71b02 100644 --- a/Lib/test/test_listcomps.py +++ b/Lib/test/test_listcomps.py @@ -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} 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 00000000000000..91e8a33f59fe47 --- /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 again. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 7017cc6c0e295f..cc9081d984b528 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -25,10 +25,16 @@ static PyMemberDef frame_memberlist[] = { static PyObject * frame_getlocals(PyFrameObject *f, void *closure) { - if (PyFrame_FastToLocalsWithError(f) < 0) - return NULL; - PyObject *locals = f->f_frame->f_locals; - return Py_NewRef(locals); + if (f == NULL) { + PyErr_BadInternalCall(); + return -1; + } + 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 @@ -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; From 12ea2ef0f1ca78d4cfb01961dda90a56f6f3aa5a Mon Sep 17 00:00:00 2001 From: Carl Meyer Date: Wed, 6 Sep 2023 15:38:52 -0600 Subject: [PATCH 2/3] Update Objects/frameobject.c Co-authored-by: Radislav Chugunov <52372310+chgnrdv@users.noreply.github.com> --- Objects/frameobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index cc9081d984b528..53764a41ca010a 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -27,7 +27,7 @@ frame_getlocals(PyFrameObject *f, void *closure) { if (f == NULL) { PyErr_BadInternalCall(); - return -1; + return NULL; } assert(!_PyFrame_IsIncomplete(f->f_frame)); PyObject *locals = _PyFrame_GetLocals(f->f_frame, 1); From 15fd4c28ca95ca9869e39636ad483a1e9545c260 Mon Sep 17 00:00:00 2001 From: Carl Meyer Date: Thu, 7 Sep 2023 07:15:21 -0600 Subject: [PATCH 3/3] Update 2023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst Co-authored-by: Jelle Zijlstra --- .../2023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 91e8a33f59fe47..94a143b86b6708 100644 --- 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 @@ -1,2 +1,2 @@ Make iteration variables of module- and class-scoped comprehensions visible -to pdb again. +to pdb and other tools that use ``frame.f_locals`` again.