Skip to content
Prev Previous commit
Next Next commit
fix definition of 'in a class block'
  • Loading branch information
carljm committed May 17, 2023
commit 948bc1a9e846bad2a86d4e61bf5ff3b3ef6c218e
7 changes: 7 additions & 0 deletions Lib/test/test_listcomps.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,13 @@ class C:
outputs = {"vals": [(0, 2), (1, 2)]}
self._check_in_scopes(code, outputs, scopes=["function"])

def test_nested_has_free_var(self):
code = """
items = [a for a in [1] if [a for _ in [0]]]
"""
outputs = {"items": [1]}
self._check_in_scopes(code, outputs, scopes=["class"])



__test__ = {'doctests' : doctests}
Expand Down
3 changes: 2 additions & 1 deletion Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -5421,6 +5421,7 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
PySTEntryObject *entry,
inlined_comprehension_state *state)
{
int in_class_block = (c->u->u_ste->ste_type == ClassBlock) && !c->u->u_in_inlined_comp;
c->u->u_in_inlined_comp++;
// iterate over names bound in the comprehension and ensure we isolate
// them from the outer scope as needed
Expand All @@ -5433,7 +5434,7 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
// at all; DEF_LOCAL | DEF_NONLOCAL can occur in the case of an
// assignment expression to a nonlocal in the comprehension, these don't
// need handling here since they shouldn't be isolated
if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || c->u->u_ste->ste_type == ClassBlock) {
if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || in_class_block) {
if (!_PyST_IsFunctionLike(c->u->u_ste)) {
// non-function scope: override this name to use fast locals
PyObject *orig = PyDict_GetItem(c->u->u_metadata.u_fasthidden, k);
Expand Down