Issue #26914: Fix formatting of lists in PEP 420

Patch by Ned Batchelder.
This commit is contained in:
Berker Peksag 2016-05-03 10:36:46 +03:00
parent 30ad98f0b1
commit 936292e0c4
1 changed files with 78 additions and 69 deletions

View File

@ -28,20 +28,25 @@ Terminology
Within this PEP: Within this PEP:
* "package" refers to Python packages as defined by Python's import * "package" refers to Python packages as defined by Python's import
statement. statement.
* "distribution" refers to separately installable sets of Python
modules as stored in the Python package index, and installed by * "distribution" refers to separately installable sets of Python
distutils or setuptools. modules as stored in the Python package index, and installed by
* "vendor package" refers to groups of files installed by an distutils or setuptools.
operating system's packaging mechanism (e.g. Debian or Redhat
packages install on Linux systems). * "vendor package" refers to groups of files installed by an
* "regular package" refers to packages as they are implemented in operating system's packaging mechanism (e.g. Debian or Redhat
Python 3.2 and earlier. 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
* "legacy portion" refers to a portion that uses ``__path__`` Python 3.2 and earlier.
manipulation in order to implement namespace packages.
* "portion" refers to a set of files in a single directory (possibly
stored in a zip file) that contribute to a namespace package.
* "legacy portion" refers to a portion that uses ``__path__``
manipulation in order to implement namespace packages.
This PEP defines a new type of package, the "namespace package". This PEP defines a new type of package, the "namespace package".
@ -115,16 +120,16 @@ A namespace package will not be constrained by a fixed ``__path__``,
computed from the parent path at namespace package creation time. computed from the parent path at namespace package creation time.
Consider the standard library ``encodings`` package: Consider the standard library ``encodings`` package:
1. Suppose that ``encodings`` becomes a namespace package. 1. Suppose that ``encodings`` becomes a namespace package.
2. It sometimes gets imported during interpreter startup to 2. It sometimes gets imported during interpreter startup to
initialize the standard io streams. initialize the standard io streams.
3. An application modifies ``sys.path`` after startup and wants to 3. An application modifies ``sys.path`` after startup and wants to
contribute additional encodings from new path entries. contribute additional encodings from new path entries.
4. An attempt is made to import an encoding from an ``encodings`` 4. An attempt is made to import an encoding from an ``encodings``
portion that is found on a path entry added in step 3. portion that is found on a path entry added in step 3.
If the import system was restricted to only finding portions along the If the import system was restricted to only finding portions along the
value of ``sys.path`` that existed at the time the ``encodings`` value of ``sys.path`` that existed at the time the ``encodings``
@ -158,29 +163,29 @@ iterate over each directory in the parent path as it does in Python
3.2. While looking for a module or package named "foo", for each 3.2. While looking for a module or package named "foo", for each
directory in the parent path: directory in the parent path:
* If ``<directory>/foo/__init__.py`` is found, a regular package is * If ``<directory>/foo/__init__.py`` is found, a regular package is
imported and returned. imported and returned.
* If not, but ``<directory>/foo.{py,pyc,so,pyd}`` is found, a module * If not, but ``<directory>/foo.{py,pyc,so,pyd}`` is found, a module
is imported and returned. The exact list of extension varies by is imported and returned. The exact list of extension varies by
platform and whether the -O flag is specified. The list here is platform and whether the -O flag is specified. The list here is
representative. representative.
* If not, but ``<directory>/foo`` is found and is a directory, it is * If not, but ``<directory>/foo`` is found and is a directory, it is
recorded and the scan continues with the next directory in the recorded and the scan continues with the next directory in the
parent path. parent path.
* Otherwise the scan continues with the next directory in the parent * Otherwise the scan continues with the next directory in the parent
path. path.
If the scan completes without returning a module or package, and at If the scan completes without returning a module or package, and at
least one directory was recorded, then a namespace package is created. least one directory was recorded, then a namespace package is created.
The new namespace package: The new namespace package:
* Has a ``__path__`` attribute set to an iterable of the path strings * Has a ``__path__`` attribute set to an iterable of the path strings
that were found and recorded during the scan. that were found and recorded during the scan.
* Does not have a ``__file__`` attribute. * Does not have a ``__file__`` attribute.
Note that if "import foo" is executed and "foo" is found as a Note that if "import foo" is executed and "foo" is found as a
namespace package (using the above rules), then "foo" is immediately namespace package (using the above rules), then "foo" is immediately
@ -247,20 +252,20 @@ Differences between namespace packages and regular packages
Namespace packages and regular packages are very similar. The Namespace packages and regular packages are very similar. The
differences are: differences are:
* Portions of namespace packages need not all come from the same * Portions of namespace packages need not all come from the same
directory structure, or even from the same loader. Regular packages directory structure, or even from the same loader. Regular packages
are self-contained: all parts live in the same directory hierarchy. are self-contained: all parts live in the same directory hierarchy.
* Namespace packages have no ``__file__`` attribute. * Namespace packages have no ``__file__`` attribute.
* Namespace packages' ``__path__`` attribute is a read-only iterable * Namespace packages' ``__path__`` attribute is a read-only iterable
of strings, which is automatically updated when the parent path is of strings, which is automatically updated when the parent path is
modified. modified.
* Namespace packages have no ``__init__.py`` module. * Namespace packages have no ``__init__.py`` module.
* Namespace packages have a different type of object for their * Namespace packages have a different type of object for their
``__loader__`` attribute. ``__loader__`` attribute.
Namespace packages in the standard library Namespace packages in the standard library
@ -441,29 +446,29 @@ ImportWarning would be raised.
Nick Coghlan presented a list of his objections to this proposal [4]_. Nick Coghlan presented a list of his objections to this proposal [4]_.
They are: They are:
1. Implicit package directories go against the Zen of Python. 1. Implicit package directories go against the Zen of Python.
2. Implicit package directories pose awkward backwards compatibility 2. Implicit package directories pose awkward backwards compatibility
challenges. challenges.
3. Implicit package directories introduce ambiguity into file system 3. Implicit package directories introduce ambiguity into file system
layouts. layouts.
4. Implicit package directories will permanently entrench current 4. Implicit package directories will permanently entrench current
newbie-hostile behavior in ``__main__``. newbie-hostile behavior in ``__main__``.
Nick later gave a detailed response to his own objections [5]_, which Nick later gave a detailed response to his own objections [5]_, which
is summarized here: is summarized here:
1. The practicality of this PEP wins over other proposals and the 1. The practicality of this PEP wins over other proposals and the
status quo. status quo.
2. Minor backward compatibility issues are okay, as long as they are 2. Minor backward compatibility issues are okay, as long as they are
properly documented. properly documented.
3. This will be addressed in PEP 395. 3. This will be addressed in PEP 395.
4. This will also be addressed in PEP 395. 4. This will also be addressed in PEP 395.
The inclusion of namespace packages in the standard library was The inclusion of namespace packages in the standard library was
motivated by Martin v. Löwis, who wanted the ``encodings`` package to motivated by Martin v. Löwis, who wanted the ``encodings`` package to
@ -547,17 +552,21 @@ optional protocol is added to PEP 302 loaders. Loaders can implement a
This method should return the string to be used verbatim as the repr of the 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: 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()`` * 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 method, call it with a single argument, which is the module object. The
value returned is used as the module's repr. value returned is used as the module's repr.
* If an exception occurs in ``module_repr()``, the exception is
caught and discarded, and the calculation of the module's repr * If an exception occurs in ``module_repr()``, the exception is
continues as if ``module_repr()`` did not exist. caught and discarded, and the calculation of the module's repr
* If the module has an ``__file__`` attribute, this is used as part of the continues as if ``module_repr()`` did not exist.
module's repr.
* If the module has no ``__file__`` but does have an ``__loader__``, then the * If the module has an ``__file__`` attribute, this is used as part of the
loader's repr is used as part of the module's repr. module's repr.
* Otherwise, just use the module's ``__name__`` in the 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.
Here is a snippet showing how namespace module reprs are calculated Here is a snippet showing how namespace module reprs are calculated
from its loader:: from its loader::