8000 gh-96497: Mangle name before symtable lookup in 'symtable_extend_name… · diegorusso/cpython@35a3ec5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 35a3ec5

Browse files
wookie184diegorusso
authored andcommitted
pythongh-96497: Mangle name before symtable lookup in 'symtable_extend_namedexpr_scope' (pythonGH-96561)
1 parent a2ccb7a commit 35a3ec5

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

Lib/test/test_named_expressions.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,16 @@ def test_named_expression_invalid_set_comprehension_iterable_expression(self):
298298
with self.assertRaisesRegex(SyntaxError, msg):
299299
exec(f"lambda: {code}", {}) # Function scope
300300

301+
def test_named_expression_invalid_mangled_class_variables(self):
302+
code = """class Foo:
303+
def bar(self):
304+
[[(__x:=2) for _ in range(2)] for __x in range(2)]
305+
"""
306+
307+
with self.assertRaisesRegex(SyntaxError,
308+
"assignment expression cannot rebind comprehension iteration variable '__x'"):
309+
exec(code, {}, {})
310+
301311

302312
class NamedExpressionAssignmentTest(unittest.TestCase):
303313

@@ -674,6 +684,18 @@ def test_named_expression_scope_in_genexp(self):
674684
for idx, elem in enumerate(genexp):
675685
self.assertEqual(elem, b[idx] + a)
676686

687+
def test_named_expression_scope_mangled_names(self):
688+
class Foo:
689+
def f(self_):
690+
global __x1
691+
__x1 = 0
692+
[_Foo__x1 := 1 for a in [2]]
693+
self.assertEqual(__x1, 1)
694+
[__x1 := 2 for a in [3]]
695+
self.assertEqual(__x1, 2)
696+
697+
Foo().f()
698+
self.assertEqual(_Foo__x1, 2)
677699

678700
if __name__ == "__main__":
679701
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix incorrect resolution of mangled class variables used in assignment
2+
expressions in comprehensions.

Python/symtable.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,16 +1359,22 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
13591359
}
13601360

13611361
static long
1362-
symtable_lookup(struct symtable *st, PyObject *name)
1362+
symtable_lookup_entry(struct symtable *st, PySTEntryObject *ste, PyObject *name)
13631363
{
13641364
PyObject *mangled = _Py_Mangle(st->st_private, name);
13651365
if (!mangled)
13661366
return 0;
1367-
long ret = _PyST_GetSymbol(st->st_cur, mangled);
1367+
long ret = _PyST_GetSymbol(ste, mangled);
13681368
Py_DECREF(mangled);
13691369
return ret;
13701370
}
13711371

1372+
static long
1373+
symtable_lookup(struct symtable *st, PyObject *name)
1374+
{
1375+
return symtable_lookup_entry(st, st->st_cur, name);
1376+
}
1377+
13721378
static int
13731379
symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste,
13741380
int lineno, int col_offset, int end_lineno, int end_col_offset)
@@ -2009,7 +2015,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
20092015
* binding conflict with iteration variables, otherwise skip it
20102016
*/
20112017
if (ste->ste_comprehension) {
2012-
long target_in_scope = _PyST_GetSymbol(ste, target_name);
2018+
long target_in_scope = symtable_lookup_entry(st, ste, target_name);
20132019
if ((target_in_scope & DEF_COMP_ITER) &&
20142020
(target_in_scope & DEF_LOCAL)) {
20152021
PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name);
@@ -2025,7 +2031,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
20252031

20262032
/* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */
20272033
if (ste->ste_type == FunctionBlock) {
2028-
long target_in_scope = _PyST_GetSymbol(ste, target_name);
2034+
long target_in_scope = symtable_lookup_entry(st, ste, target_name);
20292035
if (target_in_scope & DEF_GLOBAL) {
20302036
if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e)))
20312037
VISIT_QUIT(st, 0);

0 commit comments

Comments
 (0)
0