[Python-Dev] New relative import issue

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
>          test_b.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 test_b.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 test_b.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 test_b.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