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.)