[Distutils] Problems with Python eggs/setuptools
Phillip J. Eby
pje at telecommunity.com
Fri Aug 5 22:31:22 CEST 2005
At 07:29 PM 8/5/2005 +0200, Walter Dörwald wrote:
>I've started to play around with your easy_install script, since managing
>our packages gets more complicated with each version.
>After I've installed setuptools via ez_setup.py I've tried downloading the
>ll-xist package via "python -m easy_install ll-xist" but got a stack trace
>instead (see the attached stacktrace.txt). The problem seems to be the
>umlaut in my name. As PyPI requires UTF-8 encoded strings now, I've put a
> author=u"Walter Dörwald".encode("utf-8")
>in my setup.py when I registered the package (but a plain
> author=u"Walter Dörwald"
>in the setup.py in the package).
>To work around this problem it's possible to set the system default
>encoding to Latin-1. I don't know if this is a problem with setuptools or
>distutils, but doing a simple "python setup.py install" works.
Note that this problem is a distutils problem writing PKG-INFO files; it's
not anything specific to setuptools. I would recommend you use the
.encode('utf-8') workaround until there is an official policy for the
distutils to deal with encodings in PKG-INFO.
>The other problem seems more severe: ll-xist is installed as the packages
>ll.xist, but the package init file ll/__init__.py is *not* provided by
>this package, but by the ll-core package instead. If I understood
>correctly distributing subpackages via setuptools only works if the
>package init file is empty, which it isn't in this case.
Technically, you can do it, it's just not guaranteed that the non-empty one
will be executed, unless it's first on sys.path.
> Is there any workaround for this?
You can distribute an identical __init__.py with each distribution that
shares that parent package. If there is too much to duplicate, I would
suggest moving the contents out to a module (e.g. _my_init.py), and then
putting something like this in the __init__.py of each distributed package:
import pkg_resources; del pkg_resources
from _my_init import *
and make sure that all the distributions that don't contain the _my_init
module have declared a dependency to the one that does.
The reason for the pkg_resources import is to ensure that it has a chance
to set up the namespace package; if the modules were installed via a .pth
file, and pkg_resources has not been imported yet, then the runtime system
may not have made the package a namespace package yet, and it absolutely
needs to be before the _my_init module gets imported, so that it will be on
the package __path__.
On occasion I've thought of maybe executing *all* the __init__ modules, but
it seems potentially error-prone. If you want to try it, change this line
in the _handle_ns routine of pkg_resources:
module = sys.modules.get(packageName) or loader.load_module(packageName)
to read instead:
module = loader.load_module(packageName)
and this will cause it to load *all* of the __init__ modules. However, the
order of execution is still not guaranteed, and I'm not certain that it
might not cause an __init__ to be reloaded if its grandparent directory is
included twice on sys.path. Anyway, let me know if that change works for
you, and I will think some more on the "load all __init__ modules"
strategy. Even if I do implement it, I will want to mainly advise people
to use empty __init__ modules for any new namespace packages they create.
More information about the Distutils-SIG