views:

90

answers:

2

I have just joined a project with a rather large existing code base. We develop in linux and do not use and IDE. We run through the command line. I'm trying to figure out how to get python to search for the right path when I run project modules. For instance, when I run something like:

python 'someprojectfile.py'

I get

ImportError: no module named core.'somemodule'

I get this for all of my imports to I assume it's a pathing issue.

TLDR:

How do I get Python to search ~/codez/project/ and all the files and folders for *.py files during import statements.

+1  A: 

There are a few possible ways to do this:

  • Set the environment variable PYTHONPATH to a colon-separated list of directories to search for imported modules.
  • In your program, use sys.path.append('/path/to/search') to add the names of directories you want Python to search for imported modules. sys.path is just the list of directories Python searches every time it gets asked to import a module, and you can alter it as needed (although I wouldn't recommend removing any of the standard directories!). Any directories you put in the environment variable PYTHONPATH will be inserted into sys.path when Python starts up.
  • Use site.addsitedir to add a directory to sys.path. The difference between this and just plain appending is that when you use addsitedir, it also looks for .pth files within that directory and uses them to possibly add additional directories to sys.path based on the contents of the files. See the documentation for more detail.

Which one of these you want to use depends on your situation. Remember that when you distribute your project to other users, they typically install it in such a manner that the Python code files will be automatically detected by Python's importer (i.e. packages are usually installed in the site-packages directory), so if you mess with sys.path in your code, that may be unnecessary and might even have adverse effects when that code runs on another computer. For development, I would venture a guess that setting PYTHONPATH is usually the best way to go.

However, when you're using something that just runs on your own computer (or when you have nonstandard setups, e.g. sometimes in web app frameworks), it's not entirely uncommon to do something like

from os.path import dirname
sys.path.append(dirname(__file__))
David Zaslavsky
So if I had like say 15 subdirectories, I would have to individually add each one?
themaestro
and could you give an example of a command line argument to change PYTHONPATH?
themaestro
To set `PYTHONPATH`: in `.bashrc` or whatever startup file your shell uses (if it's not Bash), write `export PYTHONPATH=$PYTHONPATH:$HOME/codez/project`. But if you have a bunch of subdirectories, I'd make a `.pth` file and use `site.addsitedir`. You can create a module `sitecustomize` that can call the function for you; try putting it at `~/.local/lib/python2.6/sitecustomize.py` (substitute your Python version) so it hopefully gets automatically imported.
David Zaslavsky
I put the following in my .bashrc file and I'm still having no luck with those imports. Any ideas? How would I make a .pth file anyway?export PYTHONPATH=$PYTHONPATH:$HOME/adaifotis/codez/export PYTHONPATH=$PYTHONPATH:$HOME/adaifotis/codez/projectexport PYTHONPATH=$PYTHONPATH:$HOME/adaifotis/codez/project/coreexport PYTHONPATH=$PYTHONPATH:$HOME/adaifotis/codez/project/proxiesexport PYTHONPATH=$PYTHONPATH:$HOME/adaifotis/codez/project/conf
themaestro
Try opening up a terminal and running `echo $PYTHONPATH`. If the environment variable has been set properly, you should see a colon-separated list of directories. For information about `.pth` files, see the documentation for the `site` module which I linked to in my answer. It tells you what the contents should be and how to use them.
David Zaslavsky
A: 

You should also read about python packages, http://docs.python.org/tutorial/modules.html . From your example, I would guess that you really have a package at ~/codez/project. The file init.py in a python directory maps a directory into a namespace. If your subdirectories all have an init.py file then you only need to add the basedir to your PYTHONPATH, for example:

PYTHONPATH=$PYTHONPATH:$HOME/adaifotis/project

In addition to testing your PYTHONPATH environment variable, as David explains, you can test it in python like this:

$ python
>>> import project                      # should work if PYTHONPATH set
>>> import sys
>>> for line in sys.path: print line    # print current python path
Andrew B.