Consider the following script, which uses exec
to define two functions, one of which calls the other:
def run_code():
code = """
def foo():
print('foo')
return 1
def bar():
print('bar calls foo')
return 1 + foo()
result = bar()
"""
exec(code, globals(), locals())
print('Result: {}'.format(locals()['result']))
run_code()
I would expect to see the following output:
bar calls foo
foo
Result: 2
but instead, I get the following output+stacktrace:
bar calls foo
Traceback (most recent call last):
File "minimal.py", line 17, in <module>
run_code()
File "minimal.py", line 14, in run_code
exec(code, globals(), locals())
File "<string>", line 10, in <module>
File "<string>", line 8, in bar
NameError: name 'foo' is not defined
Interestingly, if the content of run_code
is moved into the module level, then it works fine. However, if I then replace globals()
or locals()
with a new empty dictionary, it breaks once again. I also know that putting def foo
inside bar
's body will make it work.
Why is this error occurring, and what is the proper fix?
(I know that exec
is generally frowned upon. I am using it for good reason.)