How do I create a namespace package in Python?

How do I create a namespace package in Python?


On Python 3.3 you dont have to do anything, just dont put any in your namespace package directories and it will just work. On pre-3.3, choose the pkgutil.extend_path() solution over the pkg_resources.declare_namespace() one, because its future-proof and already compatible with implicit namespace packages.

Python 3.3 introduces implicit namespace packages, see PEP 420.

This means there are now three types of object that can be created by an import foo:

  • A module represented by a file
  • A regular package, represented by a directory foo containing an file
  • A namespace package, represented by one or more directories foo without any files

Packages are modules too, but here I mean non-package module when I say module.

First it scans sys.path for a module or regular package. If it succeeds, it stops searching and creates and initalizes the module or package. If it found no module or regular package, but it found at least one directory, it creates and initializes a namespace package.

Modules and regular packages have __file__ set to the .py file they were created from. Regular and namespace packages have __path__set to the directory or directories they were created from.

When you do import, the above search happens first for foo, then if a package was found, the search for bar is done with foo.__path__as the search path instead of sys.path. If is found, foo and are created and initialized.

So how do regular packages and namespace packages mix? Normally they dont, but the old pkgutil explicit namespace package method has been extended to include implicit namespace packages.

If you have an existing regular package that has an like this:

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

… the legacy behavior is to add any other regular packages on the searched path to its __path__. But in Python 3.3, it also adds namespace packages.

So you can have the following directory structure:

├── path1
│   └── package
│       ├──
│       └──
├── path2
│   └── package
│       └──
└── path3
    └── package

… and as long as the two have the extend_path lines (and path1, path2 and path3 are in your sys.path) import, import and import package.baz will all work.

pkg_resources.declare_namespace(__name__) has not been updated to include implicit namespace packages.

Theres a standard module, called pkgutil, with which you
can append modules to a given namespace.

With the directory structure youve provided:


You should put those two lines in both Package-1/namespace/ and Package-2/namespace/ (*):

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

(* since -unless you state a dependency between them- you dont know which of them will be recognized first – see PEP 420 for more information)

As the documentation says:

This will add to the packages __path__ all subdirectories of directories on sys.path named after the package.

From now on, you should be able to distribute those two packages independently.

How do I create a namespace package in Python?

This section should be pretty self-explanatory.

In short, put the namespace code in, update to declare a namespace, and you are free to go.

Leave a Reply

Your email address will not be published. Required fields are marked *