pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/51b974b0ab360c8b91ed4730e5afc97539e5fa77

stylesheet" href="https://github.githubassets.com/assets/global-d18f184ea1a06a2c.css" /> [3.11] gh-96497: Mangle name before symtable lookup in 'symtable_exte… · python/cpython@51b974b · GitHub
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

3 files changed

Lines changed: 34 additions & 4 deletions

File tree

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy