Put two spaces after the end of sentences, so that emacs does a better job at reflowing text.
This commit is contained in:
parent
32753d298e
commit
481d0d80c3
90
pep-0420.txt
90
pep-0420.txt
|
@ -14,12 +14,12 @@ Abstract
|
|||
========
|
||||
|
||||
Namespace packages are a mechanism for splitting a single Python
|
||||
package across multiple directories on disk. In current Python
|
||||
package across multiple directories on disk. In current Python
|
||||
versions, an algorithm to compute the packages ``__path__`` must be
|
||||
formulated. With the enhancement proposed here, the import machinery
|
||||
formulated. With the enhancement proposed here, the import machinery
|
||||
itself will construct the list of directories that make up the
|
||||
package. This PEP builds upon the work started in rejected PEPs 382
|
||||
and 402. An implementation of this PEP is at [1]_.
|
||||
and 402. An implementation of this PEP is at [1]_.
|
||||
|
||||
Terminology
|
||||
===========
|
||||
|
@ -44,19 +44,19 @@ This PEP describes a new type of package, the "namespace package".
|
|||
Namespace packages today
|
||||
========================
|
||||
|
||||
Python currently provides ``pkgutil.extend_path`` to denote a package as
|
||||
a namespace package. The recommended way of using it is to put::
|
||||
Python currently provides ``pkgutil.extend_path`` to denote a package
|
||||
as a namespace package. The recommended way of using it is to put::
|
||||
|
||||
from pkgutil import extend_path
|
||||
__path__ = extend_path(__path__, __name__)
|
||||
|
||||
in the package's ``__init__.py``. Every distribution needs to provide
|
||||
in the package's ``__init__.py``. Every distribution needs to provide
|
||||
the same contents in its ``__init__.py``, so that ``extend_path`` is
|
||||
invoked independent of which portion of the package gets imported
|
||||
first. As a consequence, the package's ``__init__.py`` cannot
|
||||
first. As a consequence, the package's ``__init__.py`` cannot
|
||||
practically define any names as it depends on the order of the package
|
||||
fragments on ``sys.path`` to determine which portion is imported
|
||||
first. As a special feature, ``extend_path`` reads files named
|
||||
first. As a special feature, ``extend_path`` reads files named
|
||||
``<packagename>.pkg`` which allows declaration of additional portions.
|
||||
|
||||
setuptools provides a similar function named
|
||||
|
@ -67,7 +67,7 @@ setuptools provides a similar function named
|
|||
|
||||
In the portion's ``__init__.py``, no assignment to ``__path__`` is
|
||||
necessary, as ``declare_namespace`` modifies the package ``__path__``
|
||||
through ``sys.modules``. As a special feature, ``declare_namespace``
|
||||
through ``sys.modules``. As a special feature, ``declare_namespace``
|
||||
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.
|
||||
|
@ -81,8 +81,8 @@ Rationale
|
|||
|
||||
The current imperative approach to namespace packages has lead to
|
||||
multiple slightly-incompatible mechanisms for providing namespace
|
||||
packages. For example, pkgutil supports ``*.pkg`` files; setuptools
|
||||
doesn't. Likewise, setuptools supports inspecting zip files, and
|
||||
packages. For example, pkgutil supports ``*.pkg`` files; setuptools
|
||||
doesn't. Likewise, setuptools supports inspecting zip files, and
|
||||
supports adding portions to its ``_namespace_packages`` variable,
|
||||
whereas pkgutil doesn't.
|
||||
|
||||
|
@ -90,12 +90,12 @@ Namespace packages are designed to support being split across multiple
|
|||
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
|
||||
the namespace package. However, Linux distribution vendors (amongst
|
||||
the namespace package. However, Linux distribution vendors (amongst
|
||||
others) prefer to combine the separate portions and install them all
|
||||
into the *same* filesystem directory. This creates a potential for
|
||||
into the *same* filesystem directory. This creates a potential for
|
||||
conflict, as the portions are now attempting to provide the *same*
|
||||
file on the target system - something that is not allowed by many
|
||||
package managers. Allowing implicit namespace packages means that the
|
||||
package managers. Allowing implicit namespace packages means that the
|
||||
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
|
||||
|
@ -107,14 +107,14 @@ Specification
|
|||
Regular packages will continue to have an ``__init__.py`` and will
|
||||
reside in a single directory.
|
||||
|
||||
Namespace packages cannot contain an ``__init__.py``. As a
|
||||
Namespace packages cannot contain an ``__init__.py``. As a
|
||||
consequence, ``pkgutil.extend_path`` and
|
||||
``pkg_resources.declare_namespace`` become obsolete for purposes of
|
||||
namespace package creation. There will be no marker file or directory
|
||||
namespace package creation. There will be no marker file or directory
|
||||
for specifing a namespace package.
|
||||
|
||||
During import processing, the import machinery will continue to
|
||||
iterate over the parent path as it does in Python 3.2. While looking
|
||||
iterate over the parent path as it does in Python 3.2. While looking
|
||||
for a module or package named "foo":
|
||||
|
||||
* If ``foo/__init__.py`` is found, a regular package is imported.
|
||||
|
@ -122,7 +122,7 @@ for a module or package named "foo":
|
|||
* If not, but ``foo`` is found and is a directory, it is recorded.
|
||||
|
||||
If the scan along the parent path completes without finding a module
|
||||
or package, then a namespace package is created. The new namespace
|
||||
or package, then a namespace package is created. The new namespace
|
||||
package:
|
||||
|
||||
* Has a ``__file__`` attribute set to the first directory that was
|
||||
|
@ -132,47 +132,47 @@ package:
|
|||
|
||||
There is no mechanism to automatically recompute the ``__path__`` if
|
||||
``sys.path`` is altered after a namespace package has already been
|
||||
created. However, existing namespace utilities (like
|
||||
created. However, existing namespace utilities (like
|
||||
``pkgutil.extend_path``) can be used to update them explicitly if
|
||||
desired.
|
||||
|
||||
Note that if "import foo" is executed and "foo" is found as a
|
||||
namespace package (using the above rules), then "foo" is immediately
|
||||
created as a package. The creation of the namespace package is not
|
||||
created as a package. The creation of the namespace package is not
|
||||
deferred until a sub-level import occurs.
|
||||
|
||||
Impact on Import Finders and Loaders
|
||||
------------------------------------
|
||||
|
||||
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 namespace module's __path__, as described above.
|
||||
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
|
||||
namespace module's __path__, as described above.
|
||||
|
||||
[Consider Brett's idea to pass NamespaceLoader in to PathFinder]
|
||||
|
||||
Discussion
|
||||
==========
|
||||
|
||||
There is no intention to remove support of regular packages. If there
|
||||
There is no intention to remove support of regular packages. If there
|
||||
is no intention that a package is a namespace package, then there is a
|
||||
performance advantage to it being a regular package. Creation and
|
||||
performance advantage to it being a regular package. Creation and
|
||||
loading of the package can take place once it is located along the
|
||||
path. With namespace packages, all entries in the path must be
|
||||
path. With namespace packages, all entries in the path must be
|
||||
scanned.
|
||||
|
||||
Note that an ImportWarning will no longer be raised for a directory
|
||||
lacking an ``__init__.py`` file. Such a directory will now be imported
|
||||
as a namespace package, whereas in prior Python versions an
|
||||
lacking an ``__init__.py`` file. Such a directory will now be
|
||||
imported as a namespace package, whereas in prior Python versions an
|
||||
ImportError would be raised.
|
||||
|
||||
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]_.
|
||||
|
||||
Nick Coglan presented a list of his objections to this proposal
|
||||
[3]_. They are:
|
||||
Nick Coglan presented a list of his objections to this proposal [3]_.
|
||||
They are:
|
||||
|
||||
* Implicit package directories go against the Zen of Python
|
||||
|
||||
|
@ -192,23 +192,23 @@ Packaging Implications
|
|||
======================
|
||||
|
||||
Multiple portions of a namespace package can be installed into the
|
||||
same location, or into separate locations. For this section, suppose
|
||||
there are two portions which define "foo.bar" and "foo.baz". "foo"
|
||||
same location, or into separate locations. For this section, suppose
|
||||
there are two portions which define "foo.bar" and "foo.baz". "foo"
|
||||
itself is a namespace package.
|
||||
|
||||
If these are installed in the same location, a single directory "foo"
|
||||
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 by
|
||||
an automatic packager), care must be taken not to remove the "foo/baz"
|
||||
or "foo" directories. Note that in this case "foo" will be a namespace
|
||||
package (because it lacks an ``__init__.py``, even though all of its
|
||||
portions are in the same directory.
|
||||
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
|
||||
by an automatic packager), care must be taken not to remove the
|
||||
"foo/baz" or "foo" directories. Note that in this case "foo" will be
|
||||
a namespace package (because it lacks an ``__init__.py``, even though
|
||||
all of its portions are in the same directory.
|
||||
|
||||
If the portions are installed in different locations, two different
|
||||
"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 corresonding "foo" directories can be removed.
|
||||
"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
|
||||
corresonding "foo" directories can be removed.
|
||||
|
||||
Note that even if they are installed in the same directory, "foo.bar"
|
||||
and "foo.baz" would not have any files in common.
|
||||
|
|
Loading…
Reference in New Issue