This code works fine - it defines do_return
as a global, it defines do_proxy
as a global, and do_proxy
can resolve do_return
when called.
g1 = {}
exec("def do_return(): return 1", g1)
exec("def do_proxy(): return do_return()", g1)
merged = {**g1}
merged.pop("__builtins__")
print(merged.keys())
exec("print(do_proxy())", merged)
$ python3 main.py
dict_keys(['do_return', 'do_proxy'])
1
This code doesn't:
g1 = {}
g2 = {}
exec("def do_return(): return 1", g1)
exec("def do_proxy(): return do_return()", g2)
merged = {**g1, **g2}
merged.pop("__builtins__")
print(merged.keys())
exec("print(do_proxy())", merged)
It complaints that do_return
is not defined, even though there is a global named do_return
:
$ python3 main.py
dict_keys(['do_return', 'do_proxy'])
Traceback (most recent call last):
File "main.py", line 8, in <module>
exec("print(do_proxy())", merged)
File "<string>", line 1, in <module>
File "<string>", line 1, in do_proxy
NameError: name 'do_return' is not defined
Is there a way to merge dependent globals from multiple calls to exec
which didn't share the same globals dict when they were originally called?
The same happens if I call global do_return
inside do_proxy
(though if that was required, I would also expect the first example to fail, similarly requiring it).