[Distutils] Setuptools: omit namespace package directories?
Phillip J. Eby
pje at telecommunity.com
Mon Feb 12 01:16:39 CET 2007
At 12:15 AM 2/12/2007 +0100, Thomas Lotze wrote:
>Am Fri, 09 Feb 2007 23:01:20 +0100 schrieb Thomas Lotze:
>
> > But - what prevents the
> > __init__.py file in this directory from setting up any intermediate
> > namespaces in sys.modules and causing the real package to be looked for in
> > some convenient place that avoids directory jumping in the source tree?
>
>Nothing does. A proof-of-concept example can be found at
><http://www.thomas-lotze.de/Misc/foo.bar.baz-dev.tar.gz>. The source tree
>contains foo/__init__.py and baz/__init__.py, the former setting up some
>stuff in sys.modules using pkg_resources._handle_ns, the latter just
>printing out __file__ for proof that it has been imported. You can use
>this project both in develop mode and as an egg; I installed it using
>easy_install.
>
>Right now, a lot of os.path manipulation on __file__ is being done by
>foo/__init__.py; if this was replaced by a call to some appropriate
>pkg_resources function, the package_dir information could be used instead
>in a clean way.
>
>Also, the modules stuff gets set up all at once instead of recursively as
>declare_namespace does. Thus the intermediate namespace package foo.bar
>doesn't need an __init__.py, and it fact it doesn't even need a directory
>in the source tree. I can't see anything bad about that right now, but
>maybe a missing __init__.py does cause trouble somewhere.
It appears your goals are somewhat... confused. Namespace packages, as
I've already said, do not always even have __init__.py files existing, so
there is no place to put your example __init__.py that guarantees it will
be executed.
Remember that by definition a namespace package has no single "owner"
project. It is potentially shared across multiple projects. When
installed as an egg, each __init__.py is executed, true. But when a
project is NOT installed via egg, but rather by a system packager, the
__init__.py doesn't exist, and so cannot be executed.
Thus, the normal case for a namespace package is to have a number of
__init__.py files that is either 0 or >1. Having exactly one __init__.py
present for some namespace package is an abnormality.
Therefore, your prototype code is horribly broken, as it will corrupt
pkg_resources' internal data structures when it is run more than once -- as
it would have to be in order to support *each* project containing code
under that namespace package. (And I won't even get into the pointlessness
of wrapping module-level code in an import lock.)
More information about the Distutils-SIG
mailing list