2012-04-19 16:16:16 -04:00
|
|
|
|
PEP: 420
|
|
|
|
|
Title: Implicit Namespace Packages
|
|
|
|
|
Version: $Revision$
|
|
|
|
|
Last-Modified: $Date$
|
|
|
|
|
Author: Eric V. Smith <eric@trueblade.com>
|
|
|
|
|
Status: Draft
|
|
|
|
|
Type: Standards Track
|
|
|
|
|
Content-Type: text/x-rst
|
|
|
|
|
Created: 19-Apr-2012
|
|
|
|
|
Python-Version: 3.3
|
|
|
|
|
Post-History:
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
Namespace packages are a mechanism for splitting a single Python
|
2012-04-25 13:33:23 -04:00
|
|
|
|
package across multiple directories on disk. In current Python
|
2012-04-20 06:29:55 -04:00
|
|
|
|
versions, an algorithm to compute the packages ``__path__`` must be
|
2012-04-25 13:33:23 -04:00
|
|
|
|
formulated. With the enhancement proposed here, the import machinery
|
2012-04-19 16:16:16 -04:00
|
|
|
|
itself will construct the list of directories that make up the
|
|
|
|
|
package. This PEP builds upon the work started in rejected PEPs 382
|
2012-04-25 13:33:23 -04:00
|
|
|
|
and 402. An implementation of this PEP is at [1]_.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
Terminology
|
|
|
|
|
===========
|
|
|
|
|
|
2012-04-20 06:29:55 -04:00
|
|
|
|
Within this PEP:
|
|
|
|
|
|
|
|
|
|
* "package" refers to Python packages as defined by Python's import
|
|
|
|
|
statement.
|
|
|
|
|
* "distribution" refers to separately installable sets of Python
|
|
|
|
|
modules as stored in the Python package index, and installed by
|
|
|
|
|
distutils or setuptools.
|
|
|
|
|
* "vendor package" refers to groups of files installed by an
|
|
|
|
|
operating system's packaging mechanism (e.g. Debian or Redhat
|
|
|
|
|
packages install on Linux systems).
|
|
|
|
|
* "portion" refers to a set of files in a single directory (possibly
|
|
|
|
|
stored in a zip file) that contribute to a namespace package.
|
|
|
|
|
* "regular package" refers to packages as they are implemented in
|
2012-05-01 08:22:49 -04:00
|
|
|
|
Python 3.2 and earlier.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
2012-05-01 08:22:49 -04:00
|
|
|
|
This PEP defines a new type of package, the "namespace package".
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
Namespace packages today
|
|
|
|
|
========================
|
|
|
|
|
|
2012-04-25 13:33:23 -04:00
|
|
|
|
Python currently provides ``pkgutil.extend_path`` to denote a package
|
|
|
|
|
as a namespace package. The recommended way of using it is to put::
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
from pkgutil import extend_path
|
|
|
|
|
__path__ = extend_path(__path__, __name__)
|
|
|
|
|
|
2012-04-25 13:33:23 -04:00
|
|
|
|
in the package's ``__init__.py``. Every distribution needs to provide
|
2012-04-20 08:18:01 -04:00
|
|
|
|
the same contents in its ``__init__.py``, so that ``extend_path`` is
|
2012-04-19 16:16:16 -04:00
|
|
|
|
invoked independent of which portion of the package gets imported
|
2012-04-25 13:33:23 -04:00
|
|
|
|
first. As a consequence, the package's ``__init__.py`` cannot
|
2012-04-19 16:16:16 -04:00
|
|
|
|
practically define any names as it depends on the order of the package
|
2012-04-20 09:22:25 -04:00
|
|
|
|
fragments on ``sys.path`` to determine which portion is imported
|
2012-04-25 13:33:23 -04:00
|
|
|
|
first. As a special feature, ``extend_path`` reads files named
|
2012-04-20 09:22:25 -04:00
|
|
|
|
``<packagename>.pkg`` which allows declaration of additional portions.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
2012-04-19 18:10:05 -04:00
|
|
|
|
setuptools provides a similar function named
|
2012-04-20 06:29:55 -04:00
|
|
|
|
``pkg_resources.declare_namespace`` that is used in the form::
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
import pkg_resources
|
|
|
|
|
pkg_resources.declare_namespace(__name__)
|
|
|
|
|
|
2012-04-20 06:29:55 -04:00
|
|
|
|
In the portion's ``__init__.py``, no assignment to ``__path__`` is
|
|
|
|
|
necessary, as ``declare_namespace`` modifies the package ``__path__``
|
2012-04-25 13:33:23 -04:00
|
|
|
|
through ``sys.modules``. As a special feature, ``declare_namespace``
|
2012-04-20 06:29:55 -04:00
|
|
|
|
also supports zip files, and registers the package name internally so
|
|
|
|
|
that future additions to ``sys.path`` by setuptools can properly add
|
|
|
|
|
additional portions to each package.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
setuptools allows declaring namespace packages in a distribution's
|
2012-04-20 06:29:55 -04:00
|
|
|
|
``setup.py``, so that distribution developers don't need to put the
|
|
|
|
|
magic ``__path__`` modification into ``__init__.py`` themselves.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
Rationale
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
The current imperative approach to namespace packages has lead to
|
|
|
|
|
multiple slightly-incompatible mechanisms for providing namespace
|
2012-04-25 13:33:23 -04:00
|
|
|
|
packages. For example, pkgutil supports ``*.pkg`` files; setuptools
|
|
|
|
|
doesn't. Likewise, setuptools supports inspecting zip files, and
|
2012-04-20 06:29:55 -04:00
|
|
|
|
supports adding portions to its ``_namespace_packages`` variable,
|
|
|
|
|
whereas pkgutil doesn't.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
2012-04-20 06:20:24 -04:00
|
|
|
|
Namespace packages are designed to support being split across multiple
|
2012-04-20 08:35:55 -04:00
|
|
|
|
directories (and hence found via multiple ``sys.path`` entries). In
|
|
|
|
|
this configuration, it doesn't matter if multiple portions all provide
|
|
|
|
|
an ``__init__.py`` file, so long as each portion correctly initializes
|
2012-04-25 13:33:23 -04:00
|
|
|
|
the namespace package. However, Linux distribution vendors (amongst
|
2012-04-20 06:20:24 -04:00
|
|
|
|
others) prefer to combine the separate portions and install them all
|
2012-04-25 13:33:23 -04:00
|
|
|
|
into the *same* filesystem directory. This creates a potential for
|
2012-04-20 06:20:24 -04:00
|
|
|
|
conflict, as the portions are now attempting to provide the *same*
|
|
|
|
|
file on the target system - something that is not allowed by many
|
2012-04-25 13:33:23 -04:00
|
|
|
|
package managers. Allowing implicit namespace packages means that the
|
2012-04-20 06:20:24 -04:00
|
|
|
|
requirement to provide an ``__init__.py`` file can be dropped
|
|
|
|
|
completely, and affected portions can be installed into a common
|
|
|
|
|
directory or split across multiple directories as distributions see
|
|
|
|
|
fit.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
Specification
|
|
|
|
|
=============
|
|
|
|
|
|
2012-04-20 06:29:55 -04:00
|
|
|
|
Regular packages will continue to have an ``__init__.py`` and will
|
|
|
|
|
reside in a single directory.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
2012-04-25 13:33:23 -04:00
|
|
|
|
Namespace packages cannot contain an ``__init__.py``. As a
|
2012-04-20 08:18:01 -04:00
|
|
|
|
consequence, ``pkgutil.extend_path`` and
|
|
|
|
|
``pkg_resources.declare_namespace`` become obsolete for purposes of
|
2012-04-25 13:33:23 -04:00
|
|
|
|
namespace package creation. There will be no marker file or directory
|
2012-04-20 08:18:01 -04:00
|
|
|
|
for specifing a namespace package.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
During import processing, the import machinery will continue to
|
2012-04-25 13:33:23 -04:00
|
|
|
|
iterate over the parent path as it does in Python 3.2. While looking
|
2012-04-19 16:16:16 -04:00
|
|
|
|
for a module or package named "foo":
|
|
|
|
|
|
2012-04-20 06:29:55 -04:00
|
|
|
|
* If ``foo/__init__.py`` is found, a regular package is imported.
|
|
|
|
|
* If not, but ``foo.{py,pyc,so,pyd}`` is found, a module is imported.
|
|
|
|
|
* If not, but ``foo`` is found and is a directory, it is recorded.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
If the scan along the parent path completes without finding a module
|
2012-04-28 06:23:39 -04:00
|
|
|
|
or package and at least one directory was recorded, then a namespace
|
|
|
|
|
package is created. The new namespace package:
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
2012-04-20 06:29:55 -04:00
|
|
|
|
* Has a ``__file__`` attribute set to the first directory that was
|
|
|
|
|
found during the scan, including the trailing path separator.
|
|
|
|
|
* Has a ``__path__`` attribute set to the list of directories there
|
|
|
|
|
were found and recorded during the scan.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
2012-04-20 06:15:03 -04:00
|
|
|
|
There is no mechanism to automatically recompute the ``__path__`` if
|
|
|
|
|
``sys.path`` is altered after a namespace package has already been
|
2012-04-25 13:33:23 -04:00
|
|
|
|
created. However, existing namespace utilities (like
|
2012-04-20 08:18:01 -04:00
|
|
|
|
``pkgutil.extend_path``) can be used to update them explicitly if
|
2012-04-20 06:15:03 -04:00
|
|
|
|
desired.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
Note that if "import foo" is executed and "foo" is found as a
|
|
|
|
|
namespace package (using the above rules), then "foo" is immediately
|
2012-04-25 13:33:23 -04:00
|
|
|
|
created as a package. The creation of the namespace package is not
|
2012-04-19 16:16:16 -04:00
|
|
|
|
deferred until a sub-level import occurs.
|
|
|
|
|
|
2012-04-25 13:52:33 -04:00
|
|
|
|
A namespace package is not fundamentally different from a regular
|
|
|
|
|
package. It is just a different way of creating packages. Once a
|
|
|
|
|
namespace package is created, there is no functional difference
|
|
|
|
|
between it and a regular package. The only observable difference is
|
|
|
|
|
that the namespace package's ``__file__`` attribute will end with a
|
|
|
|
|
path separator (typically a slash or backslash, depending on the
|
|
|
|
|
platform).
|
|
|
|
|
|
2012-04-20 08:11:56 -04:00
|
|
|
|
Impact on Import Finders and Loaders
|
|
|
|
|
------------------------------------
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
2012-04-25 13:33:23 -04:00
|
|
|
|
PEP 302 defines "finders" that are called to search path elements.
|
|
|
|
|
These finders' ``find_module`` methods currently return either a
|
|
|
|
|
"loader" object or None. For a finder to contribute to namespace
|
|
|
|
|
packages, ``find_module`` will return a third type: a string. This is
|
|
|
|
|
the string that will be recorded and later used as a component of the
|
2012-04-30 19:04:39 -04:00
|
|
|
|
namespace module's ``__path__``, as described above. This string must
|
|
|
|
|
not contain a trailing path separator.
|
2012-04-24 13:05:25 -04:00
|
|
|
|
|
2012-04-30 18:05:25 -04:00
|
|
|
|
There is no impact on PEP 302 "loaders".
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
2012-04-30 19:28:54 -04:00
|
|
|
|
If an existing finder is not updated to support returning a string
|
|
|
|
|
from ``find_module``, the only impact is that such a loader will be
|
|
|
|
|
unable to provide portions of a namespace package.
|
|
|
|
|
|
2012-04-19 16:16:16 -04:00
|
|
|
|
Discussion
|
|
|
|
|
==========
|
|
|
|
|
|
2012-05-01 08:22:49 -04:00
|
|
|
|
At PyCon 2012, we had a discussion about namespace packages at which
|
|
|
|
|
PEP 382 and PEP 402 were rejected, to be replaced by this PEP [2]_.
|
|
|
|
|
|
2012-05-01 10:55:21 -04:00
|
|
|
|
There is no intention to remove support of regular packages. If a
|
|
|
|
|
developer knows that her package will never be a portion of a
|
|
|
|
|
namespace package, then there is a performance advantage to it being a
|
|
|
|
|
regular package (with an ``__init__.py``). Creation and loading of a
|
|
|
|
|
regular package can take place immediately when it is located along
|
|
|
|
|
the path. With namespace packages, all entries in the path must be
|
|
|
|
|
scanned before the package is created.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
2012-04-20 04:51:07 -04:00
|
|
|
|
Note that an ImportWarning will no longer be raised for a directory
|
2012-04-25 13:33:23 -04:00
|
|
|
|
lacking an ``__init__.py`` file. Such a directory will now be
|
|
|
|
|
imported as a namespace package, whereas in prior Python versions an
|
2012-04-26 11:05:41 -04:00
|
|
|
|
ImportWarning would be raised.
|
2012-04-19 18:56:22 -04:00
|
|
|
|
|
2012-04-25 13:33:23 -04:00
|
|
|
|
Nick Coglan presented a list of his objections to this proposal [3]_.
|
|
|
|
|
They are:
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
|
|
|
|
* Implicit package directories go against the Zen of Python
|
|
|
|
|
|
|
|
|
|
* Implicit package directories pose awkward backwards compatibility
|
|
|
|
|
challenges
|
|
|
|
|
|
|
|
|
|
* Implicit package directories introduce ambiguity into filesystem
|
|
|
|
|
layouts
|
|
|
|
|
|
|
|
|
|
* Implicit package directories will permanently entrench current
|
|
|
|
|
newbie-hostile behaviour in __main__
|
|
|
|
|
|
|
|
|
|
(These need to be addressed here.)
|
|
|
|
|
|
2012-04-27 09:03:59 -04:00
|
|
|
|
Phillip Eby asked about auto-updating of ``__path__``, instead of it
|
|
|
|
|
being a simple list [4]_. It is the intent of this PEP to get the
|
|
|
|
|
simplest possible solution working. It will be possible at a later
|
|
|
|
|
date to add such features. Several possible ways to do so were
|
|
|
|
|
discussed in the referenced email thread.
|
2012-04-19 16:16:16 -04:00
|
|
|
|
|
2012-04-25 13:28:21 -04:00
|
|
|
|
Packaging Implications
|
|
|
|
|
======================
|
|
|
|
|
|
|
|
|
|
Multiple portions of a namespace package can be installed into the
|
2012-04-26 08:30:19 -04:00
|
|
|
|
same directory, or into separate directories. For this section,
|
|
|
|
|
suppose there are two portions which define "foo.bar" and "foo.baz".
|
|
|
|
|
"foo" itself is a namespace package.
|
2012-04-25 13:28:21 -04:00
|
|
|
|
|
|
|
|
|
If these are installed in the same location, a single directory "foo"
|
2012-04-25 13:33:23 -04:00
|
|
|
|
would be in a directory that is on ``sys.path``. Inside "foo" would
|
|
|
|
|
be two directories, "bar" and "baz". If "foo.bar" is removed (perhaps
|
2012-05-01 08:22:49 -04:00
|
|
|
|
by an OS package manager), care must be taken not to remove the
|
2012-04-25 13:33:23 -04:00
|
|
|
|
"foo/baz" or "foo" directories. Note that in this case "foo" will be
|
2012-04-25 13:35:07 -04:00
|
|
|
|
a namespace package (because it lacks an ``__init__.py``), even though
|
2012-04-25 13:33:23 -04:00
|
|
|
|
all of its portions are in the same directory.
|
2012-04-25 13:28:21 -04:00
|
|
|
|
|
2012-05-01 08:22:49 -04:00
|
|
|
|
Note that "foo.bar" and "foo.baz" can be installed into the same "foo"
|
|
|
|
|
directory because they will not have any files in common.
|
|
|
|
|
|
2012-04-25 13:28:21 -04:00
|
|
|
|
If the portions are installed in different locations, two different
|
2012-04-25 13:33:23 -04:00
|
|
|
|
"foo" directories would be in directories that are on ``sys.path``.
|
|
|
|
|
"foo/bar" would be in one of these sys.path entries, and "foo/baz"
|
|
|
|
|
would be in the other. Upon removal of "foo.bar", the "foo/bar" and
|
2012-05-01 08:22:49 -04:00
|
|
|
|
corresonding "foo" directories can be completely removed. But
|
|
|
|
|
"foo/baz" and its corresponding "foo" directory cannot be removed.
|
2012-04-25 13:28:21 -04:00
|
|
|
|
|
2012-05-01 08:22:49 -04:00
|
|
|
|
It is also possible to have the "foo.bar" portion installed in a
|
|
|
|
|
directory on ``sys.path``, and have the "foo.baz" portion provided in
|
|
|
|
|
a zip file, also on ``sys.path``.
|
2012-04-24 21:21:04 -04:00
|
|
|
|
|
2012-04-19 16:16:16 -04:00
|
|
|
|
References
|
|
|
|
|
==========
|
|
|
|
|
|
2012-04-24 07:12:00 -04:00
|
|
|
|
.. [1] PEP 420 branch (http://hg.python.org/features/pep-420)
|
|
|
|
|
|
|
|
|
|
.. [2] PyCon 2012 Namespace Package discussion outcome
|
2012-04-19 16:16:16 -04:00
|
|
|
|
(http://mail.python.org/pipermail/import-sig/2012-March/000421.html)
|
|
|
|
|
|
2012-04-24 07:12:00 -04:00
|
|
|
|
.. [3] Nick Coglan's objection to the lack of marker files or directories
|
2012-04-19 16:16:16 -04:00
|
|
|
|
(http://mail.python.org/pipermail/import-sig/2012-March/000423.html)
|
|
|
|
|
|
2012-04-27 09:03:59 -04:00
|
|
|
|
.. [4] Phillip Eby's question about auto-updating __path__
|
|
|
|
|
(http://mail.python.org/pipermail/import-sig/2012-April/000468.html)
|
|
|
|
|
|
2012-04-19 16:16:16 -04:00
|
|
|
|
Copyright
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
This document has been placed in the public domain.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
..
|
|
|
|
|
Local Variables:
|
|
|
|
|
mode: indented-text
|
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
|
sentence-end-double-space: t
|
|
|
|
|
fill-column: 70
|
|
|
|
|
coding: utf-8
|
|
|
|
|
End:
|