2

(New to Python, old Java guy.) I have followed the recommendations for Python project set-up (as detailed here: What is the best project structure for a Python application?).

My structure is then:

artman
`-- artman
    +-- artman.py
    +-- util.py
    `-- test
        `-- util_test.py

...and my test code attempts unsuccessfully to import what's inside util.py that it's going to test:

import unittest
import util        # <------ Unresolved import: util

class UtilTest( unittest.TestCase ):
    def testLookForArtmanRoot( self ):
        util.lookForArtmanRoot( "." )

if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()

I'm sure this is a simple, newbie Python mistake, but despite Googling I don't know if I must amend PYTHONPATH or employ some other solution.

Community
  • 1
  • 1
Russ Bateman
  • 18,333
  • 14
  • 49
  • 65
  • 1
    Dear *Old Java guy* Take a look at [this](http://stackoverflow.com/questions/27494064/python-importerror-loading-module-within-subfolder/27494206) It is almost the same. Happy to hear that people are leaving the grand old cup of coffee to get bitten by snakes. – Bhargav Rao Dec 26 '14 at 19:15
  • 1
    (In fact, I'm not leaving it, I'm still going to be working in Java. It's just that I've joined a new shop with lots of Python guys and don't want to be the lone idiot. Thanks.) – Russ Bateman Dec 26 '14 at 21:13

1 Answers1

3

Although it is not strictly necessary, I would disambiguate the directory/package/module structure so as you learn, the purpose of every step will be clear.

artman_dir
`-- artman_pkg
    +-- __init__.py
    +-- artman.py
    +-- util.py
    +-- test
        `-- util_test.py
  • Add artman_dir to your PYTHONPATH.
  • Add an empty file called __init__.py to artman_pkg.

These two steps together allow you to

import artman_pkg

from any python script.

Then you can import util in util_test.py using an absolute import:

import artman_pkg.util as util

and the rest of the code can remain unchanged.

Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • Thanks! This is very useful information at my stage and it works perfectly. I would point out that, so far, PyDev hasn't required me to add artman_dir to my PYTHONPATH, but I don't exclude that, once built and used as a serious application, artman won't work until I do, but I'll tackle that later. – Russ Bateman Dec 26 '14 at 21:15
  • You can also use relative imports: `from . import util`. This has the advantage that it imports the package you even if you have an other package with the same name on the PYTHONPATH. – Bakuriu Dec 26 '14 at 21:30
  • @Bakuriu: there could be issues with relative imports in `__main__` module such as `util_test.py` (as I understand, OP wants to run it directly -- absolute imports should be used here). – jfs Dec 28 '14 at 06:11
  • If `test` directory is not a Python package then you could lift it to `artman_dir`. If it is a Python package then the test could be run from `artman_dir` without changing PYTHONPATH as `python -martman_pkg.test.util_test` – jfs Dec 28 '14 at 06:14