Reputation: 58
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?
Upvotes: 0
Views: 106
Reputation: 280237
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.
Upvotes: 1