3

I have a project that tries to create a new module dynamically and then in a subsequent exec statement tries to import that module.

import imp

s="""
class MyClass(object):
    def __init__(self):
        pass
    def foo(self):
        pass
"""

mod = imp.new_module("testmodule.testA")
exec s in mod.__dict__

exec "import testmodule.testA"

But this throws this exception:

Traceback (most recent call last):
File "test.py", line 14, in <module>
exec "import testmodule.testA"
File "<string>", line 1, in <module>
ImportError: No module named testmodule.testA

I've tried several things: adding it to sys.modules, creating a scope dict containing the name and the module as well. But no dice. I can see testmodule.testA when I do a print locals() in my exec statement, but I can't import it. What am I missing here?

Thank you.

mottosan
  • 466
  • 3
  • 14
  • You say you've "tried adding it to sys.modules", which would be necessary for the subsequent import to work. But that's not shown in your code. Did you actually do this as described in the answer from Martjin Pieters below? – cjs Apr 18 '19 at 10:10

1 Answers1

1

You'll need to add your module to the sys.modules structure for import to find it:

import sys
sys.modules['testmodule.testA'] = mod

You already have the module object however and there is not much point in importing it again. mod is a reference to what Python would otherwise 'import' already.

The following would work without an import call:

mod.MyClass

If you need the module in an exec call, add it to the namespace there:

exec 'instance = MyClass()' in {'MyClass': mod.MyClass}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Well, the second `exec` statement was an example. In reality, it would be a string serialized form of some code that requires the code/module from the first `exec`. So basically, I am generating a bunch of module objects and then running a method that uses the generated modules and acts as an entry point to some process. – mottosan Oct 04 '14 at 13:16