Description
Bug report
If I have a walrus target with a private name, contained in a comprehension, the compiler mangles the name just fine.
However, if the name is declared global in a function containing the comprehension, the walrus is supposed to assign to the global variable with the mangled name.
Instead, I get a SyntaxError. BTW, if I use the mangled name instead of the private name in the walrus, it works fine.
Example:
>>> class C:
... def f():
... global __x
... __x = 0
... [_C__x := 1 for a in [2]]
... [__x := 2 for a in [3]] # BUG
...
File "<stdin>", line 6
SyntaxError: no binding for nonlocal '_C__x' found
Line 4 correctly assigns the global variable _C__x
= 0, and line 5 assigns it = 1.
Disassembly of this program, without line 5:
4 0 LOAD_CONST 1 (0)
2 STORE_GLOBAL 0 (_C__x)
5 4 LOAD_CONST 2 (<code object <listcomp> at 0x00000213F83B4C90, file "<stdin>", line 5>)
6 LOAD_CONST 3 ('C.f.<locals>.<listcomp>')
8 MAKE_FUNCTION 0
10 LOAD_CONST 4 ((2,))
12 GET_ITER
14 CALL_FUNCTION 1
16 POP_TOP
18 LOAD_CONST 0 (None)
20 RETURN_VALUE
Disassembly of <code object <listcomp> at 0x00000213F83B4C90, file "<stdin>", line 5>:
5 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 12 (to 18)
6 STORE_FAST 1 (a)
8 LOAD_CONST 0 (1)
10 DUP_TOP
12 STORE_GLOBAL 0 (_C__x)
14 LIST_APPEND 2
16 JUMP_ABSOLUTE 4
>> 18 RETURN_VALUE```
Your environment
- CPython versions tested on: Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)] on win32
- Operating system and architecture: Windows 10.
Suggestions
I don't have the facility to debug the compiler code, so I can only speculate about the cause of the bug.
It would appear that when __x is found in the NamedExpr, which is part of the , it somehow is using the original name __x in a symbol lookup instead of the mangled name _C__x. I don't know which symbol table is involved, but whichever it is, __x is of course not in it. And the SyntaxError has the mangled name in the message.
Linked PRs
- gh-96497: Mangle name before symtable lookup in 'symtable_extend_namedexpr_scope' #96561
- [3.12] gh-96497: Mangle name before symtable lookup in 'symtable_extend_namedexpr_scope' (GH-96561) #115603
- [3.11] gh-96497: Mangle name before symtable lookup in 'symtable_extend_namedexpr_scope' (GH-96561) #115604