Traceback (most recent call last):
File "/tmp/t.py", line 12, in <module>
assert l["result"]() == 3
^^^^^^^^^^^^^
File "<example>", line 5, in result
NameError: name 'a' is not defined
Is there a way to make this work?
NB I do not want to modify the input string. (In my “real” usecase that wouldn’t be feasible.)
When you pass separate globals and locals to exec, it runs it kinda like this:
class locals:
a=1
b=2
def result():
return a+b
The function is not in a nested scope, it’s running in its own scope directly off the globals.
Do you actually need separate locals in this way? If not, try this:
exec(code, g)
assert g["result"]() == 3
which will run the code as though it were a module, rather than as though it were a class. This is generally sufficient.
It’s not flaky; it’s just doing something different from what you may have expected. Were you expecting it to act as if the code was inside a function, or were you looking for some other behaviour? In any case, what it’s doing is something that is definitely of value, and is well defined, but probably not what you want here.