Reputation: 4974
I'm failing to import a module from a parent directory in 2.7 and I'm not sure why. Any help would be appreciated.
I have a Python package with this directory structure:
source/
|--foo/__init__.py
|--foo/bar/__init__.py
|--foo/bar/nested.py
|--foo/top.py
tests/
|--helpers/__init__.py
|--foo/__init__.py
|--foo/bar/__init__.py
|--foo/bar/nested_test.py
|--foo/top_test.py
setup.py
setup.cfg
tox.ini
I use pytest
and python setup.py test
almost interchangeably to run my tests with. In tox.ini
, I have:
[tox]
envlist = py27
[testenv]
commands = pytest
deps = pytest
[pytest]
testpaths=tests
Note, that I don't actually use tox
to run my tests.
And in setup.cfg
:
[aliases]
test=pytest
I'm not 100% sure, but I think this setup means that when I run python setup.py test
, it actually just runs pytest
, so it might not be relevant to this question.
In foo/top_test.py
, I can import tests.helpers
, but in foo/bar/nested_test.py
, the same import raises an ImportError
saying that the module was not found.
Why is this and how can I fix it?
I've attempted to run pytest
and python setup.py test
in a clean virtualenv after running pip install pytest
and pip install -r requirements.txt
(My requirements.txt
is basically a blank file with -e
and -i
set to a private repo.
Note: I can open up a python
REPL from the root directory of the project and import tests._helper
without any problems.
I've also attempted to add tests
and tests.helpers
to the tests_require
argument in the setuptools.setup()
function in setup.py
, but it looks like it attempts to install those from the remote index instead of using the local modules.
I've also attempted appending to sys.path
in my foo/bar/nested_test.py:
import os
import sys
sys.path.append(os.path.realpath('tests'))
Upvotes: 2
Views: 727
Reputation: 14655
One thing I notice is you don't appear to have a tests/__init__.py
. Not sure if that matters in your case but it does in the example below.
Whenever I have a problem like this I try and setup a simplified test case with as few things as possible. Get setuptools, pytest and all that other noise out of the way and just debug the module structure and then add those back after you know your structure is sound.
For example, here's a script
#!/bin/bash
rm -rf tests
mkdir -p tests/foo/bar
mkdir -p tests/helpers
touch tests/__init__.py
touch tests/foo/__init__.py
touch tests/foo/bar/__init__.py
touch tests/helpers/__init__.py
echo 'import tests.helpers' > tests/foo/top_test.py
echo 'import tests.helpers' > tests/foo/bar/nested_test.py
tree tests
python -c 'import tests.foo.bar.nested_test; print "got here"'
which produces the output
tests
|-- __init__.py
|-- foo
| |-- __init__.py
| |-- bar
| | |-- __init__.py
| | `-- nested_test.py
| `-- top_test.py
`-- helpers
`-- __init__.py
3 directories, 6 files
got here
Once you have a simple script like this you can interactively experiment with your imports.
Upvotes: 1