Ramy
Ramy

Reputation: 21261

something wrong with my pythonpath

I know this is a dumb question but i'm stumped. My directory structure used to look like this:

-src
  |
  -module.py
  -program.py

when this what my directory structure, I referenced module from program and all was well.

I've since changed my directory structure to this:

-src
  |
  -__init.py
  -module.py
  |
  -programDir
    |
    -__init.py
    -program.py

now, of course, I can't reach the module from program. How can I reference src as a package. I tried to create an

__init__.py 

file in the src directory, but no luck.

Moar deets: import statements i've tried in program.py:

import module

and

from src import module

the first one worked when the other module and program were in the same directory.

error i'm getting:

ImportError: No module named module

and just for the record: No, my module and program are not called module OR program

update: I've tried this in my program.py file:

from ...src import module

and

from ..src import module

both are giving me:

ValueError: Attempted relative import in non-package

Upvotes: 0

Views: 2276

Answers (6)

Rod
Rod

Reputation: 55752

If you use program as part of a package, in another python module, such as

import src.programDir.program as p

p.some_method()

you can use relative import in program.py, assuming you are creating a package with src (__init__.py in both src and programDir)

from .. import module

If not, for example you are calling program.py from the command line, you must add the directory containing src to your search path either by modifying sys.path or the PYTHONPATH env var, before importing.

Upvotes: 0

Bill Lynch
Bill Lynch

Reputation: 81916

Couldn't you use PEP 328 to solve this?

Upvotes: 1

GreenMatt
GreenMatt

Reputation: 18570

For starters, I recommend reading the entry Modifying Python's Search Path in the docs.

It might be frowned upon by some, but if you wish to modify the PYTHONPATH from within your program, according to the documentation's standard modules entry you can use the sys.path.append method:

import sys
sys.path.append('..')
import module

Upvotes: 2

Filip Dupanović
Filip Dupanović

Reputation: 33640

You need to add __init__.py to /programDir to interpret the directory as a package. Once a package, you can import the package's contents.

So, in your case, if /src is on the PYTHONPATH, from module.py you can import program.py with from programDir import program.

Upvotes: 0

Mahmoud Abdelkader
Mahmoud Abdelkader

Reputation: 24919

The first one worked because Python's sys.path's first entry is '' which means it will look for module names in the current working directory from which you've executed the Python interpreter.

The issue you seem to have is that the directory located at src is not set on your PYTHONPATH. So, you can do is set the PYTHONPATH environment variable explicitly.

Here's an example using bash:

export PYTHONPATH=PATH_TO_SRC:${PYTHONPATH}

then run your program as normal

Another approach is that you can explicitly set sys.path by appending to it upon execution of your program.

So, in your program.py, you would have:

if __name__ == '__main__':
    import os
    import sys
    sys.path.append(os.path.dirname(os.path.dirname(__file__)))
    your_main_function()

Lastly, for serious python development, you should consider virtualenv and virtualenvwrapper as it will take care of most of these things for you.

Upvotes: 0

orip
orip

Reputation: 75437

If you run program.py directly, with python program.py or with #!, then module.py's directory should be in the PYTHONPATH for import module to work. This can be achieved using a helper shell script that's kept in programDir, for instance, and looks something like:

#!/bin/bash

script_dir=`dirname $0`
# Add the script's parent directory to the PYTHONPATH
export PYTHONPATH=$PYTHONPATH:$script_dir/..

python $script_dir/program.py

Another, probably better, way would be to have program.py export a "main()" function, and create a helper python script at src/program that looks like:

#!/usr/bin/env python
from programDir.program import main
main()

In this case, you can use relative imports in src/programDir/program.py, so this should work:

from .. import module

Upvotes: 0

Related Questions