Python – Using importlib to Dynamically Import Modules with Relative Imports

pythonpython-3.x

I am trying to figure out how to programmatically execute a module that contains relative imports.

psuedo code

spec = importlib.util.spec_from_file_location(name, path)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)

Where name is the class, and path is the absolute path to the .py

When the module that is being loaded contains relative imports, the call to the exec_module throws the following exception:

attempted relative import with no known parent package

Is there a way to programmatically execute a python module that itself contains relative imports? If so, how?

Best Answer

Your code works fine for me, as is.

One possible issue is what the value of the name you're using is. In order for relative imports to work, you need to fully specify the module name (e.g. name = "package1.package2.mymodule").

For example:

runimport.py

import importlib
import os

name = "testpack.inside" # NOT "inside"

spec = importlib.util.spec_from_file_location(name, 
    os.path.join(os.path.dirname(__file__), 'testpack/inside.py'))
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)

testpack/init.py

# empty

testpack/inside.py

from . import otherinside
print('I got', otherinside.data)

testpack/otherinside.py

data = 'other inside'

Now, python3 runimport.py prints "I got other inside". If you replace the name with "inside", it throws the error you describe.

Related Question