[Python-Dev] New relative import issue (original) (raw)

Giovanni Bajo rasky at develer.com
Sun Sep 24 01:11:06 CEST 2006


Armin Rigo wrote:

This doesn't match my experience, which is that sys.path hackery is required in any project that is larger than one directory, but is not itself a library. [...]

myapp/ main.py a/ init.py b.py testb.py c/ init.py

This theoretical example shows main.py (the main entry point) at the root of the package directories - it is the only place where it can be if it needs to import the packages a and c. The module a.b can import c, too (and this is not bad design - think about c as a package regrouping utilities that make sense for the whole application). But then the testing script testb.py cannot import the whole application any more. Imports of a or c will fail, and even a relative import of b will crash when b tries to import c. The only way I can think of is to insert the root directory in sys.path from within testb.py, and then use absolute imports.

This also matches my experience, but I never used sys.path hackery for this kind of things. I either set PYTHONPATH while I work on "myapp" (which I consider not such a big trouble after all, and surely much less invasive than adding specific Python code tweaking sys.path into all the tests), or, even more simply, I run the test from myapp main directory (manually typing "myapp/b/test_b.py").

There is also another possibility, which is having a smarter test framework where you can specify substrings of test names: I don't know py.test in detail, but in my own framework I can say something like "./run_tests.py PAT", which basically means "recursively discover and run all files named test_NAME, and where PAT is a substring of NAME).

(For example, to support this way of organizing applications, the 'py' lib provides a call py.magic.autopath() that can be dropped at the start of testb.py. It hacks sys.path by guessing the "real" root according to how many levels of init.py there are...)

Since I consider this more of an environmental problem, I would not find satisfying any kind of solution at the single module level (and even less so one requiring so much guess-work as this one).

Giovanni Bajo



More information about the Python-Dev mailing list