views:

83

answers:

4

what's wrong with my imports?

App folder structure:

myapp
 - models/models.py contains SpotModel()
 - tests/tests.py contains TestSpotModel(unittest.TestCase). tests.py imports "from myapp.models.models import *" which works like a charm
 - scripts/import.py contains "from myapp.models.models import *"

the problem is that import.py when executed results in an error: "ImportError: No module named myapp.models.models" but tests.py runs.

I have __init__.py files in myapp/__init__.py, myapp/models/__init__.py, myapp/tests/__init__.py and as mentioned, running the unit tests using nosetests works as intended.

A: 

It is __init__.py not init.py. Make sure each of the directory in hierarchy contains it in order to be able to import.

EDIT: I managed to reproduce it. Here's the directory structure:

cesar@cesar-laptop:/tmp/asdasd$ tree
.
`-- myapp
    |-- __init__.py
    |-- models
    |   |-- __init__.py
    |   `-- models.py
    |-- scripts
    |   |-- data.py
    |   `-- __init__.py
    `-- tests
        |-- __init__.py
        `-- tests.py

I put the following code at the very beginning of the data.py to narrow down the problem:

import sys
import pprint

pprint.pprint(sys.path)

from myapp.models.models import *

Running the data.py the way OP indicated yeilds ImportError:

cesar@cesar-laptop:/tmp/asdasd$ python myapp/scripts/data.py
['/tmp/asdasd/myapp/scripts',
 '/usr/lib/python2.6',
 '/usr/lib/python2.6/plat-linux2',
 '/usr/lib/python2.6/lib-tk',
 -- Skipped --
'/usr/local/lib/python2.6/dist-packages']
Traceback (most recent call last):
  File "myapp/scripts/data.py", line 6, in 
    from myapp.models.models import *
ImportError: No module named myapp.models.models

But this way works like a charm:

cesar@cesar-laptop:/tmp/asdasd$ python -m myapp.scripts.data
['',
 '/usr/lib/python2.6',
 '/usr/lib/python2.6/plat-linux2',
 '/usr/lib/python2.6/lib-tk',
 -- Skipped --
'/usr/local/lib/python2.6/dist-packages']

Note the difference in the first entry of sys.path.

Ihor Kaharlichenko
(this was a markdown formatting error.)
bobince
He wrote `__init__.py`, but initially without backticks, so markdown thought it should display it bold.
delnan
Do I need an __init__.py inside the scripts folder as well? I tried adding it, but it's still the same error
kristian nissen
+1  A: 

How are you executing import.py? What is the current working directory when you do so?

The myapp directory must be on the Python path (ie. inside one of the directories listed in sys.path) for you to be able to import it. Python automatically adds the current working directory to the path list at interpreter startup time.

So if the directory that contains myapp is not added to the path manually (eg. using the PYTHONPATH environment variable, or adding it to sys.path in sitecustomize.py), you will need to be in the directory containing myapp when you run the script. If you're inside the myapp directory itself, you won't be able to import the myapp package.

bobince
I am executing it like this python myapp/scripts/import.py
kristian nissen
A: 

Your sys.path is clearly not set the same way when you're running the test and when you're running the script. Do

import sys
print(sys.path)

at the top of both modules to confirm that. Then, fix the one that's wrong (by appending to sys.path the parent directory of myapp in the case where it's missing.

Alex Martelli
A: 

Unless you forgot to mention it, you don't have a __init__.py in myapp/scripts, so myapp/scripts/import.py is not a module of myapp.

Unless myapp is in your global path somehow, the script can't find it because it won't be looking for it in the right place.

Either make your scripts folder a module by adding a __init__.py to it, move the scripts up the filesystem hierarchy (either into myapp or into its parent folder) or install myapp into your path (i.e. move it to your packages folder, e.g. /usr/lib/python2.6/dist-packages/).

Alan