Relative import#
This page discusses the implementation details of relative imports in Python, as well as the most common issues associated with their use.
Resolving#
Python resolves the relative imports using the __package__ attribute of the importing module. If the __package__ attribute is set to None or an empty string (''), an ImportError: attempted relative import with no known parent package is raised.
The following cells creates folder with python code.
#init
mkdir package
The module supposed to be imported:
#file package/import_me.py
print("I was imported")
The importing module:
#file package/load.py
print("package:", __package__)
from . import import_me
If the module is run as a script, it will have the __package__ = None.
python3 package/load.py
true
package: None
Traceback (most recent call last):
File "/tmp/tmprh915u9z/package/load.py", line 2, in <module>
from . import import_me
ImportError: attempted relative import with no known parent package
Python is unable to resolve the relative import.
The following cell runs imports the file as a python module, resulting in __package__=package.
python3 -m package.load
package: package
I was imported
The relative importing goes fine.
Importing module#
A typical source of confusion is when a module cannot use relative imports when run as a Python script, but everything works fine when it is imported by another Python module runned as scirpt.
The most likely reason is that the __package__ attribute is set by the import machinery of the entry point script.
Check out this stackoverflow discussion of what actually happens.
The following cells create the folder with python source files that utilise the relative import mechanism.
#init
mkdir package
#file package/import_me.py
print("I was imported")
#file package/load.py
print("package:", __package__)
from . import import_me
As expected, the pure call to the file using relative import fails.
python3 package/load.py
true
package: None
Traceback (most recent call last):
File "/tmp/tmp__8ia4y7/package/load.py", line 2, in <module>
from . import import_me
ImportError: attempted relative import with no known parent package
However, if you create and run the other entry point file that explicitly specifies the package, there are no issues.
#file load.py
from package import load
python3 load.py
package: package
I was imported