Why the default sys.path[0] insertion? (It breaks my code.)

Geoff Gerrietts geoff at gerrietts.net
Thu Dec 19 21:02:10 EST 2002


Quoting Robb Shecter (rs at onsitetech.com):
> Apparently this is because the script I executed is in the mpm 
> directory, and this becomes sys.path[0].  And this causes subpackages of 
> mpm to be imported as if they were top-level packages.  So, two things 
> occur to me:

I think you're misinterpreting the way this works.

When you issue an import statement, the directory wherein the module
currently running lives, is the first place that gets checked. This
may seem confusing given the framework you've developed, but it's
really the only natural way to manage imports without requiring
explicit manipulation of sys.path.

Given the way you've set your framework up, there aren't a lot of ways
to handle your particular situation; you've created an inadvertant
namespace conflict, as cleanly as if you were to name one of your
packages "sys".

The easiest solution is to not create a namespace conflict. I don't
know why you have ui code in two places, but I trust there's plenty of
reason. Maybe you could make the name verbose enough that the
distinction between "ui" the package and "mpm.ui" is obvious? Maybe
not.

A second solution is to make both "ui" and "mpm" sub-packages of some
parent package, then import "ui" explicitly through its parent. This
has the advantage of presenting a single directory at the top level,
but maybe that's not an advantage for your application; it has been
for all of mine. 

Your solution also works, where you have a top-level file that
provides an alias for ui -- or even access to it. If that top-level
script (say "dummy.py") imports ui, you can import the toplevel script
and refer to dummy.ui -- assuming, of course, you've set up your path
to point at the root.

> 1) This behavior is inconsistent:  Programmers cannot use relative 
> package specs in the import statement.  But in this one case, the import 
> statement is being interpreted relatively!

Relative only to the directory in which the running code is operating,
yes. You're not the first to comment on it, and undoubtedly won't be
the last. But it is a lot more convenient when files inside a
particular package can refer to one another without needing special
sys.path settings.


> This is aggravated because I like to put demo/test code into every 
> module so it can be executed alone.  So I have a dozen 
> 'mini-applications' which don't work.
> 
> Comments?

I put lots of test code in my stuff, too. I don't commonly need to
make an effort to avoid namespace conflicts, but in the rare cases I
do, I resolve them with option 2. Consider:

  myapp/
       /__init__.py
       /mymodel/
               /__init__.py
               /myview.py
               /mydb.py
       /myview/
              /__init__.py
              /hiswidget.py
              /herwidget.py


Given this layout, and given that PYTHONPATH points to myapp, I can
get at any file in the tree from any other.

Ordinarily, though, it's easier to take advantage of having access to
all my immediate neighbors, and I never have a reason to import
modules from another package -- that typically violates the Law of
Demeter.

Good Luck,
--G.

-- 
Geoff Gerrietts <geoff @ gerrietts.net> "Many a man's reputation would not 
                                         know his character if they met on 
http://www.gerrietts.net/                the street." --Elbert Hubbard




More information about the Python-list mailing list