[Distutils] Help with easy_install

Phillip J. Eby pje at telecommunity.com
Mon Dec 1 23:24:51 CET 2008

At 08:58 PM 12/1/2008 +0000, Martin Manns wrote:
>And indeed there is no sub-folder pyspread in site-packages and therefore no
>module _widgets that can be found.

That's got nothing to do with the import error.  The import error is 
because of the sys.path issue that I described in my previous email:

> > Offhand, my guess is that you're using pyspread.pyspread as a main
> > program, and also trying to import things from the pyspread
> > package.  That won't work correctly, because Python puts the
> > directory containing the __main__ script as the first entry on
> > sys.path -- meaning that when you try to import from the pyspread
> > *package*, you instead wind up importing from the pyspread
> > *script*.


>My idea of the directory structure is as follows:
>+ Everything but the main script that is in /usr/bin
>resides in [...]/site-packages/pyspread
>+ The modules are imported directly (without pyspread.[mymodule]
>Probably this is a bad idea.

It's a *very* bad idea -- and not because of the distutils or 
setuptools, either.

For one thing, you can end up with two copies of the same module in 
sys.modules under different names, i.e. both as '_foo' and 
'pyspread._foo', and then you can end up with duplicate classes, 
making isinstance() tests fail (among other potential oddities).

IOW, putting a __main__ script inside a package is bad juju where 
Python is concerned.  Also naming that __main__ script the *same name 
as the package* then borders on insanity.  ;-)

That's why Robert Kern was saying you need to rename pyspread.py to 
something else, and then use package imports only.  That will keep 
you from running afoul of the duplication problem.

>However, with the pyspread.pth file in
>site-packages, it works.

Yeah, that's just hiding the problem, it's not really fixing 
it.  Also, it's in very bad taste for a setup.py script to 
unconditionally write files; as it stands, somebody running "setup.py 
--help" will get a .pth file installed...  and NOT to their 
configured --install-lib, either!  (i.e., it may write to somewhere 
*other* than where they told the distutils to install the package).

>I just made a deb that has all files in an own directory in /usr/lib/pyspread
>and the images etc. in /usr/share/pyspread
>Perhaps, this can be done with easy_install, too.

Ah, here's where your problem is.  Instead of using get_python_lib() 
to find the default package directory, i.e.:

  LIBPREFIX = distutils.sysconfig.get_python_lib() + '/pyspread/'
  ICONPREFIX = distutils.sysconfig.get_python_lib() + '/pyspread/'

Do this instead:

  import os.path
  LIBPREFIX = ICONPREFIX = os.path.dirname(__file__)

This will work with both distutils and setuptools, including cases 
where somebody installs your program someplace other than the 
system-wide site-packages directory.  (E.g. using "setup.py install 

Also, by using __file__, setuptools will be able to notice that 
you're accessing your own package contents directly, and will install 
your package unzipped.

In short, all of these changes will only improve your results and 
packaging, whether your users are using distutils or setuptools to install it.

More information about the Distutils-SIG mailing list