zezollo zezollo - 6 months ago 40
Python Question

ImportError shows up with py.test, but not when running the app

Unlike in this question:
Importing modules from a sibling directory for use with py.test
I can import something from my app, but there's an import error (looking like a circular dependency) that raises from 'inside'

myapp
while running the test and not when running
myapp
alone:

$ python3 myapp/myapp.py
Some dummy string (correct output)


But:

$ python3 -m pytest
================================================================= test session starts =================================================================
platform linux -- Python 3.4.3, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: /home/nico/temp/projects_structures/test04/myapp, inifile:
plugins: cov-2.2.1
collected 0 items / 1 errors

======================================================================= ERRORS ========================================================================
________________________________________________________ ERROR collecting tests/test_things.py ________________________________________________________
tests/test_things.py:4: in <module>
from myapp.lib.core.base import do_things
myapp/lib/core/base.py:1: in <module>
from lib import something
E ImportError: No module named 'lib'
=============================================================== 1 error in 0.05 seconds ===============================================================


As you can see, the problem is not the
import
statement from the test file. It's raised from 'inside'
myapp
.

Here is the complete structure:

.
└── myapp
├── myapp
│   ├── __init__.py
│   ├── lib
│   │   ├── core
│   │   │   ├── base.py
│   │   │   └── __init__.py
│   │   └── __init__.py
│   └── myapp.py
└── tests
└── test_things.py


myapp.py contains:

#!/usr/bin/env python3

from lib.core import base

base.do_things()


lib/__init__.py contains:

something = "Some dummy string (correct output)"


base.py contains:

from lib import something

def do_things():
print(something)
return True


and test_things contains:

import unittest
import sys
sys.path.insert(0, '..')
from myapp.lib.core.base import do_things

class DoThingsTestCase(unittest.TestCase):

def test_do_things(self):
self.assertTrue(do_things())

if __name__ == '__main__':
unittest.main()


And
$PYTHONPATH
seems correctly set (so this:
Py.test No module named *
doesn't answer my problem). (Or if this is not correct, how can I correct it?)

$ echo $PYTHONPATH
/home/nico/temp/projects_structures/test04/myapp/myapp

Answer

Setting the PYTHONPATH should do the trick.

$ export PYTHONPATH=<ABSOLUTE PATH TO TOPMOST myapp dir>

and from myapp run

$ root py.test tests/test_things.py