8000 [3.11] gh-96497: Mangle name before symtable lookup in 'symtable_exte… · python/cpython@51b974b · GitHub
[go: up one dir, main page]

Skip to content

Commit 51b974b

Browse files
[3.11] gh-96497: Mangle name before symtable lookup in 'symtable_extend_namedexpr_scope' (GH-96561) (GH-115604)
(cherry picked from commit 664965a) Co-authored-by: wookie184 <wookie1840@gmail.com>
1 parent 5b6e358 commit 51b974b

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
@@ -222,6 +222,16 @@ def test_named_expression_invalid_set_comprehension_iterable_expression(self):
222222
with self.assertRaisesRegex(SyntaxError, msg):
223223
exec(f"lambda: {code}", {}) # Function scope
224224

225+
def test_named_expression_invalid_mangled_class_variables(self):
226+
code = """class Foo:
227+
def bar(self):
228+
[[(__x:=2) for _ in range(2)] for __x in range(2)]
229+
"""
230+
231+
with self.assertRaisesRegex(SyntaxError,
232+
"assignment expression cannot rebind comprehension iteration variable '__x'"):
233+
exec(code, {}, {})
234+
225235

226236
class NamedExpressionAssignmentTest(unittest.TestCase):
227237

@@ -598,6 +608,18 @@ def test_named_expression_scope_in_genexp(self):
598608
for idx, elem in enumerate(genexp):
599609
self.assertEqual(elem, b[idx] + a)
600610

611+
def test_named_expression_scope_mangled_names(self):
612+
class Foo:
613+
def f(self_):
614+
global __x1
615+
__x1 = 0
616+
[_Foo__x1 := 1 for a in [2]]
617+
self.assertEqual(__x1, 1)
618+
[__x1 := 2 for a in [3]]
619+
self.assertEqual(__x1, 2)
620+
621+
Foo().f()
622+
self.assertEqual(_Foo__x1, 2)
601623

602624
if __name__ == "__main__":
603625
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
@@ -1042,16 +1042,22 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
10421042
}
10431043

10441044
static long
1045-
symtable_lookup(struct symtable *st, PyObject *name)
1045+
symtable_lookup_entry(struct symtable *st, PySTEntryObject *ste, PyObject *name)
10461046
{
10471047
PyObject *mangled = _Py_Mangle(st->st_private, name);
10481048
if (!mangled)
10491049
return 0;
1050-
long ret = _PyST_GetSymbol(st->st_cur, mangled);
1050+
long ret = _PyST_GetSymbol(ste, mangled);
10511051
Py_DECREF(mangled);
10521052
return ret;
10531053
}
10541054

1055+
static long
1056+
symtable_lookup(struct symtable *st, PyObject *name)
1057+
{
1058+
return symtable_lookup_entry(st, st->st_cur, name);
1059+
}
1060+
10551061
static int
10561062
symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste,
10571063
int lineno, int col_offset, int end_lineno, int end_col_offset)
@@ -1525,7 +1531,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
15251531
* binding conflict with iteration variables, otherwise skip it
15261532
*/
15271533
if (ste->ste_comprehension) {
1528-
long target_in_scope = _PyST_GetSymbol(ste, target_name);
1534+
long target_in_scope = symtable_lookup_entry(st, ste, target_name);
15291535
if (target_in_scope & DEF_COMP_ITER) {
15301536
PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name);
15311537
PyErr_RangedSyntaxLocationObject(st->st_filename,
@@ -1540,7 +1546,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
15401546

15411547
/* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */
15421548
if (ste->ste_type == FunctionBlock) {
1543-
long target_in_scope = _PyST_GetSymbol(ste, target_name);
1549+
long target_in_scope = symtable_lookup_entry(st, ste, target_name);
15441550
if (target_in_scope & DEF_GLOBAL) {
15451551
if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e)))
15461552
VISIT_QUIT(st, 0);

0 commit comments

Comments
 (0)
0