Correctness: sys.path.append("..")

Paul Boddie paul at boddie.net
Wed Jan 9 05:37:24 EST 2002


"Mark McEahern" <marklists at mceahern.com> wrote in message news:<mailman.1010528484.30835.python-list at python.org>...
> Jeremy Bowers
> > I've taken to sticking this on top of my files in the subdirectories:
> >
> > import sys
> > if ".." not in sys.path:
> > 	sys.path.append("..")

I can think of a reason for doing this, but more on that below.

> Suppose you have the following structure:
> 
> 	/myproj/biz/customer.py
> 	/myproj/presentation/layout.py
> 	/myproj/data/tabular.py
> 
> and you have a module in myproj that needs to use modules in biz,
> presentation, and data:
> 
> 	from myproj.biz import customer
> 	from myproj.presentation import layout
> 	from myproj.data import tabular
> 
> That to me seems preferable to mucking with sys.path.

Well, there was a discussion about this a few months ago where someone
subsequently went away and developed an alternative import scheme
which allowed subpackages to reference their sibling subpackages. I
don't think that it went as far as using Acquisition, though. :-)

Whilst I think that the above solution is justified - I use it myself
- one place where it seems tempting to modify sys.path is where a
program inside a package is being run as a "client" of a package. For
example:

  projects
    - myproj
      - __init__.py
      - module.py
      - test.py

Consider the contents of 'test.py' to be the following:

  import myproj.module
  myproj.module.do_something()

Here, if one changes into the 'projects' directory and invokes the
test program...

  python myproj/test.py

...the result may well be an ImportError caused when Python can't find
'myproj'. One solution is to change the import statement:

  import module

Another solution is to insert the stated modification to sys.path. Yet
another solution is to set PYTHONPATH before running the test program
(here with 'bash'):

  PYTHONPATH=. python myproj/test.py

The moral of this tale, probably, is that files inside packages always
behave as part of such packages, but finding the root of the package
isn't always possible (for some reason). Consider adding a file in
'projects' called 'exttest.py':

  import myproj.test

Running this new program directly...

  python exttest.py

...actually imports the test program and causes it to perform its own
import with success! So, starting off in a directory which contains
the root of the package somehow "helps" Python to find the package
later on.

Paul



More information about the Python-list mailing list