Fixes ModuleNotFoundError
exceptions from absolute imports by automatically adding the entire project to sys.path
.
This is similar to what PyCharm does when a directory is marked as Sources Root
.
pip install fiximport
import fiximport
import mymodule.userutils
import mymodule.config
[...]
fiximport
must come before the absolute imports.fiximport
only needs to be added to files intended to be invoked by the CLI.
Eg,python cool_script.py
.fiximport
is safe and idempotent. You could add it to every file, if you wished.
📁 coolproject
📁 src
📄 weather.py
📁 scripts
📄 printweather.py
from src.weather import get_weather
print(f"The weather today is {get_weather('Bellingham, WA')}")
$ python printweather.py
Traceback (most recent call last):
File "printweather.py", line 1, in <module>
from src.weather import get_weather
ModuleNotFoundError: No module named 'src'
import fiximport
from src.weather import get_weather
print(f"The weather today is {get_weather('Bellingham, WA')}")
$ python printweather.py
The weather today is 67°F
fiximport
identifies the project root by iterating up, until the first "root type files" are found.- If the project root cannot be found heuristically, it defaults to one folder above the python file that called
import fiximport
. - After the root is heuristically found, all folders with a
python
file inside are added tosys.path
. This enables absolute imports to "just work".
This is not a robust permanent solution to python's import system, but it should cover simple projects nicely.
- Avoid naming collisions within your project. If there are two folders named
utils
, egfoo1/utils
andfoo2/utils
, add the prefix:from foo2.utils import check_file
. - Avoid naming collisions with common libraries. Eg
math
,statistics
,tempfile
, etc.