Relative imports - ModuleNotFoundError: No module named x

PythonPython 3.xPackagePython ImportRelative Import

Python Problem Overview


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. :)

Python Solutions


Solution 1 - Python

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.

Solution 2 - Python

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

def loaded():
    string = does_something()
    print(string)

main.py

from lib import mody

mody.loaded()

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

Solution 3 - Python

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
    │   ├── __init__.py
    │   ├── a.py
    └── anotherpackage
        ├── __init__.py
        ├── b.py
        ├── c.py
        └── mysubpackage
            ├── __init__.py
            └── 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

Solution 4 - Python

Setting PYTHONPATH can also help with this problem.

Here is how it can be done on Windows

set PYTHONPATH=.

Solution 5 - Python

You can simply add following file to your tests directory, and then python will run it before the tests

__init__.py file

import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

Solution 6 - Python

Set PYTHONPATH environment variable in root project directory.

Considering UNIX-like:

export PYTHONPATH=.

Solution 7 - Python

Tried your example

from . import config

>got the following SystemError:
>/usr/bin/python3.4 test.py
Traceback (most recent call last):
File "test.py", line 1, in
from . import config
SystemError: Parent module '' not loaded, cannot perform relative import


This will work for me:

import config
print('debug=%s'%config.debug)

>>>debug=True

Tested with Python:3.4.2 - PyCharm 2016.3.2


Beside this PyCharm offers you to Import this name.
You hav to click on config and a help icon appears. enter image description here

Solution 8 - Python

Declare correct sys.path list before you call module:

import os, sys
    
#'/home/user/example/parent/child'
current_path = os.path.abspath('.')

#'/home/user/example/parent'
parent_path = os.path.dirname(current_path)

sys.path.append(parent_path)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'child.settings')

Solution 9 - Python

If you are using python 3+ then try adding below lines

import os, sys
dir_path = os.path.dirname(os.path.realpath(__file__))
parent_dir_path = os.path.abspath(os.path.join(dir_path, os.pardir))
sys.path.insert(0, parent_dir_path)

Solution 10 - Python

Try

from . import config

What that does is import from the same folder level. If you directly try to import it assumes it's a subordinate

Solution 11 - Python

I am working in a Linux machine. I had the same issue when I run python my_module/__main__.py.

The error is fixed, if you run the command export PYTHONPATH=. before your run your script.

export PYTHONPATH=.
python my_module/__main__.py

Solution 12 - Python

This example works on Python 3.6.

I suggest going to Run -> Edit Configurations in PyCharm, deleting any entries there, and trying to run the code through PyCharm again.

If that doesn't work, check your project interpreter (Settings -> Project Interpreter) and run configuration defaults (Run -> Edit Configurations...).

Solution 13 - Python

As was stated in the comments to the original post, this seemed to be an issue with the python interpreter I was using for whatever reason, and not something wrong with the python scripts. I switched over from the WinPython bundle to the official python 3.6 from python.org and it worked just fine. thanks for the help everyone :)

Solution 14 - Python

For me, simply adding the current directory worked.

Using the following structure:

└── myproject
    ├── a.py
    └── b.py

a.py:

from b import some_object
# returns ModuleNotFound error

from myproject.b import some_object
# works

Solution 15 - Python

You may use these statements to set the working directory, which worked for me with python3

import os
import sys
sys.path.insert(1, os.getcwd())

Solution 16 - Python

In my experience, PYTHONPATH environment variable does not work everytime.

In my case, my pytest only worked when I added the absolute path: sys.path.insert( 0, "/Users/bob/project/repo/lambda" )

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionblitzmannView Question on Stackoverflow
Solution 1 - PythonIgonatoView Answer on Stackoverflow
Solution 2 - Pythonuser3159377View Answer on Stackoverflow
Solution 3 - PythonGiorgos MyrianthousView Answer on Stackoverflow
Solution 4 - PythonSantosh PillaiView Answer on Stackoverflow
Solution 5 - PythonVinod RaneView Answer on Stackoverflow
Solution 6 - PythonmanasouzaView Answer on Stackoverflow
Solution 7 - PythonstovflView Answer on Stackoverflow
Solution 8 - PythonHoangYellView Answer on Stackoverflow
Solution 9 - PythonVivek GargView Answer on Stackoverflow
Solution 10 - PythonArny BoyView Answer on Stackoverflow
Solution 11 - PythonGeorgios SyngouroglouView Answer on Stackoverflow
Solution 12 - PythonCarson CraneView Answer on Stackoverflow
Solution 13 - PythonblitzmannView Answer on Stackoverflow
Solution 14 - Pythonhalf of a glazierView Answer on Stackoverflow
Solution 15 - PythonjoydebaView Answer on Stackoverflow
Solution 16 - PythonllincolnatalView Answer on Stackoverflow