# Relative imports – ModuleNotFoundError: No module named x – Dev

The best answers to the question “Relative imports – ModuleNotFoundError: No module named x” in the category Dev.

QUESTION:

This is the first time I’ve really sat down and tried python 3, and seem to be failing miserably. I have the following two files:

1. test.py
2. config.py

config.py has a few functions defined in it as well as a few variables. I’ve stripped it down to the following:

config.py

debug = True


test.py

import config
print (config.debug)


I also have an __init__.py

However, I’m getting the following error:

ModuleNotFoundError: No module named 'config'


I’m aware that the py3 convention is to use absolute imports:

from . import config


However, this leads to the following error:

ImportError: cannot import name 'config'


So I’m at a loss as to what to do here… Any help is greatly appreciated. 🙂

I figured it out. Very frustrating, especially coming from python2.

You have to add a . to the module, regardless of whether or not it is relative or absolute.

I created the directory setup as follows.

/main.py
--/lib
--/__init__.py
--/mody.py
--/modx.py


modx.py

def does_something():
return "I gave you this string."


mody.py

from modx import does_something

string = does_something()
print(string)


main.py

from lib import mody



when I execute main, this is what happens

$python main.py Traceback (most recent call last): File "main.py", line 2, in <module> from lib import mody File "/mnt/c/Users/Austin/Dropbox/Source/Python/virtualenviron/mock/package/lib/mody.py", line 1, in <module> from modx import does_something ImportError: No module named 'modx'  I ran 2to3, and the core output was this RefactoringTool: Refactored lib/mody.py --- lib/mody.py (original) +++ lib/mody.py (refactored) @@ -1,4 +1,4 @@ -from modx import does_something +from .modx import does_something def loaded(): string = does_something() RefactoringTool: Files that need to be modified: RefactoringTool: lib/modx.py RefactoringTool: lib/mody.py  I had to modify mody.py’s import statement to fix it try: from modx import does_something except ImportError: from .modx import does_something def loaded(): string = does_something() print(string)  Then I ran main.py again and got the expected output $ python main.py
I gave you this string.


Lastly, just to clean it up and make it portable between 2 and 3.

from __future__ import absolute_import
from .modx import does_something


TL;DR: You can’t do relative imports from the file you execute since __main__ module is not a part of a package.

Absolute imports – import something available on sys.path

Relative imports – import something relative to the current module, must be a part of a package

If you’re running both variants in exactly the same way, one of them should work. Here is an example that should help you understand what’s going on. Let’s add another main.py file with the overall directory structure like this:

.
./main.py
./ryan/__init__.py
./ryan/config.py
./ryan/test.py


And let’s update test.py to see what’s going on:

# config.py
debug = True

# test.py
print(__name__)

try:
# Trying to find module in the parent package
from . import config
print(config.debug)
del config
except ImportError:
print('Relative import failed')

try:
# Trying to find module on sys.path
import config
print(config.debug)
except ModuleNotFoundError:
print('Absolute import failed')

# main.py
import ryan.test


Let’s run test.py first:

$python ryan/test.py __main__ Relative import failed True  Here “test” is the __main__ module and doesn’t know anything about belonging to a package. However import config should work, since the ryan folder will be added to sys.path. Let’s run main.py instead: $ python main.py
ryan.test
True
Absolute import failed


And here test is inside of the “ryan” package and can perform relative imports. import config fails since implicit relative imports are not allowed in Python 3.

Hope this helped.

P.S.: If you’re sticking with Python 3 there is no more need for __init__.py files.

Setting PYTHONPATH can also help with this problem.

Here is how it can be done on Windows

set PYTHONPATH=.

You have to append your project’s path to PYTHONPATH and make sure to use absolute imports.

For UNIX (Linux, OSX, …)

export PYTHONPATH="\${PYTHONPATH}:/path/to/your/project/"


For Windows

set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\project\


Absolute imports

Assuming that we have the following project structure,

└── myproject
├── mypackage
│   ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py


just make sure to reference each import starting from the project’s root directory. For instance,

# in module a.py
import anotherpackage.mysubpackage.d

# in module b
import anotherpackage.c
import mypackage.a


For a more comprehensive explanation, refer to the article How to fix ModuleNotFoundError and ImportError