Matt
Matt

Reputation: 14541

Confused about python imports

I reviewed the Python 2.7.5 documentation. I am having issues with my real project, but created a small test project here to concisely reproduce the issue. Imagine a package with the following layout stored at ~/Development/Test

Here is the structure:

Test/
    __init__.py
    foo.py
    sub/
        __init__.py
        test_foo.py

And the code (__init__.py files are empy):

foo.py

def bar():
    print("hello world")

test_foo.py

import Test.foo
# also tried from Test import foo

def main():
    foo.bar()

if __name__ == "__main__":
    main()

When trying to run test_foo.py from the terminal (i.e. python test_foo.py) I'm getting:

Traceback (most recent call last):
  File "test_foo.py", line 1, in <module>
    import Test.foo
ImportError: No module named Test.foo

I'm trying to import the main file in the package (foo.py) from the test file in the sub module (in my real project the sub module is the unit testing code). Oddly using Sublime text 2 editor and the plugin python test runner, I can run my individual tests just fine, but I cannot build the test file. It gives me the above error.

Upvotes: 1

Views: 154

Answers (2)

unutbu
unutbu

Reputation: 880359

Module names are case-sensitive. Use:

import Test.foo as foo

(The as foo is so that you can call foo.bar in main.)


You must also have ~/Development listed in PYTHONPATH.

If using Unix and your login shell is bash, to add ~/Development to PYTHONPATH edit ~/.profile to include

export PYTHONPATH=$PYTHONPATH:$HOME/Development

Here are instructions for Windows.


Further suggestions for debugging:

Place

import sys
print(sys.path)
import Test
print(Test)
import Test.foo

at the top of test_foo.py. Please post the output.

Upvotes: 1

Viktor Kerkez
Viktor Kerkez

Reputation: 46616

Runnable scripts should always be put outside the module. So if you have a module and a script that runs some code from that module, the structure should look like:

foo/
    __init__.py
    bar.py
your_script.py

And the code in your_script.py should be something like:

from foo.bar import your_func

your_func()

In case of unittesting it is a good idea (this is opinionated and everyone has his way of doing things) to place the tests inside the module so the structure should look like:

foo/
    __init__.py
    bar.py
    tests/
        test_bar.py

But in that case you shouldn't run the script directly. You should either use one of the testing frameworks like nose and run:

nosetests foo

in the directory where you placed your foo module.

Or if you used the standard unittest library, create a TestSuite and what not, run it with:

python -m unittest foo.tests.test_bar

again in the directory where you placed your foo module.

Upvotes: 1

Related Questions