I have a module object containing several function definitions. Here is a simplified example.
The source code (makes up the module "my_module")
def functionA():
print("hello")
def functionB():
functionA()
print("world")
The module is built with imp (I know it is depreciated, but my app is still on python 3.5)
ast_node = parse(source)
byte_code = compile(ast_node, 'my_module', 'exec')
my_module = imp.new_module('my_module')
exec(byte_code, __builtins__, my_module.__dict__)
I am trying to run functionB()
using exec
and passing in the full module __dict__
as the local dictionary. (I've also tried passing it in as the global dictionary without any luck)
exec("functionB()", None, my_module.__dict__)
The error I see is NameError: name 'functionA' is not defined
Is it possible to extend the local (or even global) scope to the executing function?
You don't need to "extend scope". Your problem is that you're doing things in the wrong namespaces. When you execute the module's code:
exec(byte_code, __builtins__, my_module.__dict__)
you're doing that with the built-ins namespace as globals, when you should be using the module's namespace as globals:
exec(byte_code, my_module.__dict__)
Then the module's functions will have the correct global namespace. Currently, they're all using the built-ins namespace as their global namespace.
Also, don't use __builtins__
for the built-ins namespace. It's an implementation detail, and it doesn't even work the way you think - its value is different in different contexts. Sometimes it's set to the builtins
module itself, rather than that module's dict. Instead, import builtins
and use builtins.__dict__
if you need the built-ins dict.