[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