Terry J. Reedy <tjre...@udel.edu> added the comment:
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. ---------- nosy: +gvanrossum, lys.nikolaou, pablogsal, terry.reedy stage: -> needs patch versions: +Python 3.10, Python 3.9 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue42190> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com