* Relax the constraint that m.__file__ must exist (except for built-ins)
* Describe the loader.module_repr() protocol. * Fix some misspellings.
This commit is contained in:
parent
6f8d74ea28
commit
4742457cda
61
pep-0420.txt
61
pep-0420.txt
|
@ -13,13 +13,13 @@ Post-History:
|
||||||
Abstract
|
Abstract
|
||||||
========
|
========
|
||||||
|
|
||||||
Namespace packages are a mechanism for splitting a single Python
|
Namespace packages are a mechanism for splitting a single Python package
|
||||||
package across multiple directories on disk. In current Python
|
across multiple directories on disk. In current Python versions, an algorithm
|
||||||
versions, an algorithm to compute the packages ``__path__`` must be
|
to compute the packages ``__path__`` must be formulated. With the enhancement
|
||||||
formulated. With the enhancement proposed here, the import machinery
|
proposed here, the import machinery itself will construct the list of
|
||||||
itself will construct the list of directories that make up the
|
directories that make up the package. This PEP builds upon previous work,
|
||||||
package. This PEP builds upon the work started in rejected PEPs 382
|
documented in PEP 382 and PEP 402. Those PEPs have since been rejected in
|
||||||
and 402. An implementation of this PEP is at [1]_.
|
favor of this one. An implementation of this PEP is at [1]_.
|
||||||
|
|
||||||
Terminology
|
Terminology
|
||||||
===========
|
===========
|
||||||
|
@ -111,7 +111,7 @@ Namespace packages cannot contain an ``__init__.py``. As a
|
||||||
consequence, ``pkgutil.extend_path`` and
|
consequence, ``pkgutil.extend_path`` and
|
||||||
``pkg_resources.declare_namespace`` become obsolete for purposes of
|
``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.
|
for specifying a namespace package.
|
||||||
|
|
||||||
During import processing, the import machinery will continue to
|
During import processing, the import machinery will continue to
|
||||||
iterate over each directory in the parent path as it does in Python
|
iterate over each directory in the parent path as it does in Python
|
||||||
|
@ -171,7 +171,9 @@ the string that will be recorded and later used as a component of the
|
||||||
namespace module's ``__path__``, as described above. This string must
|
namespace module's ``__path__``, as described above. This string must
|
||||||
not contain a trailing path separator.
|
not contain a trailing path separator.
|
||||||
|
|
||||||
There is no impact on PEP 302 "loaders".
|
The specification expands PEP 302 loaders to include an optional method called
|
||||||
|
``module_repr()`` which if present, is used to generate module object reprs.
|
||||||
|
See the section below for further details.
|
||||||
|
|
||||||
If an existing finder is not updated to support returning a string
|
If an existing finder is not updated to support returning a string
|
||||||
from ``find_module``, the only impact is that such a finder will be
|
from ``find_module``, the only impact is that such a finder will be
|
||||||
|
@ -200,7 +202,7 @@ If the portions are installed in different locations, two different
|
||||||
"foo" directories would be in directories that are on ``sys.path``.
|
"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"
|
"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
|
would be in the other. Upon removal of "foo.bar", the "foo/bar" and
|
||||||
corresonding "foo" directories can be completely removed. But
|
corresponding "foo" directories can be completely removed. But
|
||||||
"foo/baz" and its corresponding "foo" directory cannot be removed.
|
"foo/baz" and its corresponding "foo" directory cannot be removed.
|
||||||
|
|
||||||
It is also possible to have the "foo.bar" portion installed in a
|
It is also possible to have the "foo.bar" portion installed in a
|
||||||
|
@ -258,6 +260,45 @@ simplest possible solution working. It will be possible at a later
|
||||||
date to add such features. Several possible ways to do so were
|
date to add such features. Several possible ways to do so were
|
||||||
discussed in the referenced email thread.
|
discussed in the referenced email thread.
|
||||||
|
|
||||||
|
Module reprs
|
||||||
|
============
|
||||||
|
|
||||||
|
Previously, module reprs were hard coded based on assumptions about a module's
|
||||||
|
``__file__`` attribute. If this attribute existed and was a string, it was
|
||||||
|
assumed to be a file system path, and the module object's repr would include
|
||||||
|
this in its value. The only exception was that PEP 302 reserved missing
|
||||||
|
``__file__`` attributes to built-in modules, and in CPython, this assumption
|
||||||
|
was baked into the module object's implementation. Because of this
|
||||||
|
restriction, some module contained contrived ``__file__`` values that did not
|
||||||
|
reflect file system paths, and which could cause unexpected problems later
|
||||||
|
(e.g. ``os.path.join()`` on a non-path ``__file__`` would return gibberish).
|
||||||
|
|
||||||
|
This PEP relaxes this constraint, and leaves the setting of ``__file__`` to
|
||||||
|
the purview of the loader producing the module. Loaders may opt to leave
|
||||||
|
``__file__`` unset if no file system path is appropriate. This means that the
|
||||||
|
definitive way to determine the origin of a module is to check its
|
||||||
|
``__loader__`` attribute.
|
||||||
|
|
||||||
|
For example, namespace packages as described in this PEP will have no
|
||||||
|
``__file__`` attribute because no corresponding file exists. In order to
|
||||||
|
provide flexibility and descriptiveness in the reprs of such modules, a new
|
||||||
|
optional protocol is added to PEP 302 loaders. Loaders can implement a
|
||||||
|
``module_repr()`` method which takes a single argument, the module object.
|
||||||
|
This method should return the string to be used verbatim as the repr of the
|
||||||
|
module. The rules for producing a module repr are now standardized as:
|
||||||
|
|
||||||
|
* If the module has an ``__loader__`` and that loader has a ``module_repr()``
|
||||||
|
method, call it with a single argument, which is the module object. The
|
||||||
|
value returned is used as the module's repr.
|
||||||
|
* Exceptions from ``module_repr()`` are ignored, and the following steps
|
||||||
|
are used instead.
|
||||||
|
* If the module has an ``__file__`` attribute, this is used as part of the
|
||||||
|
module's repr.
|
||||||
|
* If the module has no ``__file__`` but does have an ``__loader__``, then the
|
||||||
|
loader's repr is used as part of the module's repr.
|
||||||
|
* Otherwise, just use the module's ``__name__`` in the repr.
|
||||||
|
|
||||||
|
|
||||||
References
|
References
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue