From Namespace Packages in distribute, I know I can make use of namespace packages to separate a big Python package into several smaller ones. It is really awesome. The document
A namespace package mainly has a particular effect when it comes time to import a sub-package. Basically, here's what happens, when importing foo.bar
sys.path
looking for something that looks like foo
.foo
for bar
.bar
is not found:
foo
is a normal package, an ImportError
is raised, indicating that foo.bar
doesn't exist.foo
is a namespace package, the importer goes back to looking through sys.path
for the next match of foo
. the ImportError
is only raised if all paths have been exhausted.So that's what it does, but doesn't explain why you might want that. Suppose you designed a big, useful library (foo
) but as part of that, you also developed a small, but very useful utility (foo.bar
) that others python programmers find useful, even when they don't have a use for the bigger library.
You could distribute them together as one big blob of a package (as you designed it) even though most of the people using it only ever import the sub-module. Your users would find this terribly inconvenient because they'd have to download the whole thing (all 200MB of it!) even though they are only really interested in a 10 line utility class. If you have an open license, you'll probably find that several people end up forking it and now there are a half dozen diverging versions of your utility module.
You could rewrite your whole library so that the utility lives outside the foo
namespace (just bar
instead of foo.bar
). You'll be able to distribute the utility separately, and some of your users will be happy, but that's a lot of work, especially considering that there actually are lots of users using the whole library, and so they'll have to rewrite their programs to use the new.
So what you really want is a way to install foo.bar
on its own, but happily coexist with foo
when that's desired too.
A namespace package allows exactly this, two totally independent installations of a foo
package can coexist. setuptools
will recognize that the two packages are designed to live next to each other and politely shift the folders/files in such a way that both are on the path and appear as foo
, one containing foo.bar
and the other containing the rest of foo
.
You'll have two different setup.py
scripts, one for each. foo/__init__.py
in both packages have to indicate that they are namespace packages so the importer knows to continue regardless of which package is discovered first.