68

I have a python application with the following directory structure:

src
 |
 +---- main
 |
 +---- util
 |
 +---- gen_py
         |
         +---- lib

In the package main, I have a python module named MyServer.py which has an import statement like:

from gen_py.lib import MyService

In order for this statement to work, I placed the following line at the beginning of MyServer.py:

import sys
sys.path.append('../gen_py/lib')

When I run MyServer.py in the terminal, I get the following error:

ImportError: No module named gen_py.lib

What I am missing here?

Prashant Kumar
  • 20,069
  • 14
  • 47
  • 63
F. Aydemir
  • 2,665
  • 5
  • 40
  • 60

6 Answers6

80

Your modification of sys.path assumes the current working directory is always in main/. This is not the case. Instead, just add the parent directory to sys.path:

import sys
import os.path

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import gen_py.lib

Don't forget to include a file __init__.py in gen_py and lib - otherwise, they won't be recognized as Python modules.

phihag
  • 278,196
  • 72
  • 453
  • 469
  • I have the same problem. I use Windows, Eclipse. What should we do in Eclipse? – Ayse Jun 11 '13 at 06:48
  • @Ceren This code should work in every IDE. Your IDE (or more precisely, the Python plugin for it) may not actually execute the Python code, in which case you probably need to configure the search path somewhere. Feel free to [ask a new question](http://stackoverflow.com/questions/ask) about that. – phihag Jun 11 '13 at 08:41
  • @phihag Thanks! I had asked a question about an hour ago, feel free to answer it =) http://stackoverflow.com/questions/17038416/eclipse-pydev-importerror-no-module-named-src-somesrcfile – Ayse Jun 11 '13 at 08:48
  • Is it possible to put this somewhere not in the my main application? I used this solution to solve my similar error but now I have a file that looks messy with imports all over the place. I thought there was a way to do this in the __init__ file but I can't find good examples. – MarkII Nov 12 '16 at 01:33
  • What does `sys.path.append(os.path.join(os.path.dirname(__file__), '..'))` resolve to? Why isn't it `sys.path.append(os.path.join('..', os.path.dirname(__file__)))`? – alex Oct 06 '17 at 18:45
  • @alex `__file__` is the location of the file. Typical values can be `myapp/foo/file.py`, `file.py`, or `/usr/local/share/myapp/foo/file.py`. `os.path.dirname(__file__)` removes the file name from each. Appending `..` gets us into the parent directory. Your proposed code is completely bonkers. For instance, the correct location when running `/usr/local/share/myapp/foo/file.py` from `/home/user/` would be `/usr/local/share/myapp/`. But `os.path.join` will return the second argument if it's an absolute path, so you're getting `/usr/local/share/myapp/foo/`. – phihag Oct 06 '17 at 19:29
  • @philhag Oh okay, I thought `os.path.join(os.path.dirname(__file__), '..')` would resolve to (for instance) `file.py/..`. That seemed a little bonkers to me. – alex Oct 06 '17 at 19:49
6

For the Python module import to work, you must have "src" in your path, not "gen_py/lib".

When processing an import like import gen_py.lib, it looks for a module gen_py, then looks for a submodule lib.

As the module gen_py won't be in "../gen_py/lib" (it'll be in ".."), the path you added will do nothing to help the import process.

Depending on where you're running it from, try adding the relative path to the "src" folder. Perhaps it's sys.path.append('..'). You might also have success running the script while inside the src folder directly, via relative paths like python main/MyServer.py

lunixbochs
  • 21,757
  • 2
  • 39
  • 47
  • That's not what I said. You don't append gen_py/lib to the path if you're importing "gen_py.lib". You append the folder gen_py is inside, which in this case is probably "..". – lunixbochs Sep 28 '11 at 18:20
5
from ..gen_py.lib import MyService

or

from main.gen_py.lib import MyService

Make sure you have a (at least empty) __init__.py file on each directory.

JBernardo
  • 32,262
  • 10
  • 90
  • 115
3

make sure to include __init__.py, which makes Python know that those directories containpackages

aychen0110
  • 301
  • 2
  • 5
3

This is if you are building a package and you are finding error in imports. I learnt it the hard way.The answer isn't to add the package to python path or to do it programatically (what if your module gets installed and your command adds it again?) thats a bad way.

The right thing to do is: 1) Use virtualenv pyvenv-3.4 or something similar 2) Activate the development mode - $python setup.py develop

harishkashyap
  • 114
  • 1
  • 8
0

Make sure if root project directory is coming up in sys.path output. If not, please add path of root project directory to sys.path.

Raghav salotra
  • 820
  • 1
  • 11
  • 23