Message380024
exec with different global and local dicts is most like executing code in a class definition, where locals is different from globals. But mimicking your exec with an actual class statement does not produce the same result.
>>> gdict = {}
>>> class C:
x = 1
def f(): global x
>>> gdict
{}
>>> C.x
1
# To continue, I reproduced the behavior in 3.10.
>>> ldict = {}
>>> exec('''
x = 1
def f(): global x''', gdict, ldict)
>>> 'x' in gdict
True
# And that putting x in gdict required the global declaration.
>>> gdict = {}
>>> exec('''
x = 1
def f(): pass''', gdict, ldict)
>>> 'x' in gdict
False
>>> 'x' in ldict
True
This seems like a bug to me too. The change is in the bytecode, not the subsequent execution thereof.
>>> dis.dis('x = 1')
1 0 LOAD_CONST 0 (1)
2 STORE_NAME 0 (x)
...
# Ditto if add '\ndef f(): pass', but here is the test case.
>>> dis.dis('x = 1\ndef f(): global x')
1 0 LOAD_CONST 0 (1)
2 STORE_GLOBAL 0 (x)
...
# Same result for 'global x; x = 1', but 'x = 1; global x' raises
SyntaxError: name 'x' is assigned to before global declaration
The change is inconsequential when locals is globals, but not when not. |
|
Date |
User |
Action |
Args |
2020-10-31 00:37:01 | terry.reedy | set | recipients:
+ terry.reedy, gvanrossum, Kevin Shweh, lys.nikolaou, pablogsal |
2020-10-31 00:37:01 | terry.reedy | set | messageid: <1604104621.85.0.491018690771.issue42190@roundup.psfhosted.org> |
2020-10-31 00:37:01 | terry.reedy | link | issue42190 messages |
2020-10-31 00:37:01 | terry.reedy | create | |
|