0

I know that there are other questions like this, none of them worked for me. I've been creating a simple python app and decided to organize it (instead of having the app and test.py in the same directory. I tried to set it up like this:

C:\Dev\project\module\test

- project
    - __init__.py
    - module
        - __init__.py
        - module.py
        - test
             - __init__.py 
             - test_module.py

Now I've tried everything i can think of to import module.py to test_module.py

import module
import project.module
import module.module
import project.module.module
from project import module
from project.module import module

None of these work. It fails with:

ImportError: No module named 'whatever i put in above'

It's driving me nuts, shouldn't this be simple? What am i missing? I added a test that shows my PYTHONPATH using import sys print sys.path. The first item in the list is C:\Dev\project\module\test

EDIT:

I tried adding init to the top level as well and that didn't help. I know I could force edit the sys.path as many of the answers suggest.

What is the right way to do it? As in, what is the standard or sensible way to build a project to avoid this issue?

Steve Miskiewicz
  • 1,114
  • 1
  • 10
  • 23

3 Answers3

0

Messing with the python path programmatically isn't usually considered great style, but it has its uses. I find it's a nice, quick way to do what you're doing (writing tests below/inside a module). Of course the easy way is to simply put your tests outside of the module. Barring that, however, just do this:

import sys
sys.path.insert(0, r'C:\Dev\project') # Add the directory containing your module.
import module

This way, you ensure that the first directory on the path is the directory that contains the module you want to import. You could also avoid hard-coding the module path (e.g. if you want to be able to move your project someplace else) by using a path that's relative to your testing script:

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

This will work no matter where you run the script from, and cross-platform.

Henry Keiter
  • 16,863
  • 7
  • 51
  • 80
0

If you only need to reach the parent directory, you can use:

import sys
sys.path.insert(0, '..')

import module

This should work on both Windows and Linux.

bohrax
  • 1,051
  • 8
  • 20
0

At I beginning of most of my python scripts, I always put the following:

# Path hack.
# http://stackoverflow.com/questions/6323860/sibling-package-imports
import os, sys
sys.path.insert(0, os.path.abspath('.'))

I think packaging is a bit screwed in python, yet this is a standard way for me to make it work :)

When executing my script, I always use the root directory as the working dir:

cd C:\Dev\project
python3 .\module\test\test_module.py

When importing submodules, I also always start the path from the root:

import module.module

or

from module.module import some_identifier
Tregoreg
  • 18,872
  • 15
  • 48
  • 69