Merge from upstream.
This commit is contained in:
commit
06737d34be
|
@ -8,6 +8,7 @@ Type: Standards Track
|
|||
Content-Type: text/x-rst
|
||||
Created: 26-Jan-2012
|
||||
Post-History: 30-Aug-2002, 01-Feb-2012, 03-Feb-2012
|
||||
Superseded-By: 415
|
||||
Resolution: http://mail.python.org/pipermail/python-dev/2012-February/116136.html
|
||||
|
||||
|
||||
|
@ -87,6 +88,10 @@ by the default exception printing routines.
|
|||
Implementation Discussion
|
||||
=========================
|
||||
|
||||
Note: after acceptance of this PEP, a cleaner implementation mechanism
|
||||
was proposed and accepted in PEP 415. Refer to that PEP for more
|
||||
details on the implementation actually used in Python 3.3.
|
||||
|
||||
Currently, ``None`` is the default for both ``__context__`` and ``__cause__``.
|
||||
In order to support ``raise ... from None`` (which would set ``__cause__`` to
|
||||
``None``) we need a different default value for ``__cause__``. Several ideas
|
||||
|
|
26
pep-0415.txt
26
pep-0415.txt
|
@ -1,24 +1,35 @@
|
|||
PEP: 415
|
||||
Title: Implementing PEP 409 differently
|
||||
Title: Implement context suppression with exception attributes
|
||||
Version: $Revision$
|
||||
Last-Modified: $Date$
|
||||
Author: Benjamin Peterson <benjamin@python.org>
|
||||
BDFL-Delegate: Nick Coghlan
|
||||
Status: Draft
|
||||
Status: Final
|
||||
Type: Standards Track
|
||||
Content-Type: text/x-rst
|
||||
Created: 26-Feb-2012
|
||||
Python-Version: 3.3
|
||||
Post-History: 26-Feb-2012
|
||||
Replaces: 409
|
||||
Resolution: http://mail.python.org/pipermail/python-dev/2012-May/119467.html
|
||||
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
||||
PEP 409 allows PEP 3134 exception contexts and causes to be suppressed when the
|
||||
exception is printed. This is done using the ``raise exc from None``
|
||||
syntax. This PEP proposes to implement context and cause suppression
|
||||
differently.
|
||||
PEP 409 introduced support for the ``raise exc from None`` construct to
|
||||
allow the display of the exception context to be explicitly suppressed.
|
||||
This PEP retains the language level changes already implemented in PEP 409,
|
||||
but replaces the underlying implementation mechanism with a simpler approach
|
||||
based on a new ``__suppress_context__`` attribute on all ``BaseException``
|
||||
instances.
|
||||
|
||||
|
||||
PEP Acceptance
|
||||
==============
|
||||
|
||||
This PEP was accepted by Nick Coghlan on the 14th of May, 2012.
|
||||
|
||||
|
||||
Rationale
|
||||
=========
|
||||
|
@ -40,6 +51,7 @@ exceptions, so it's not clear to someone inspecting an exception object why
|
|||
``__cause__`` should be set to ``Ellipsis``. Using ``Ellipsis`` by default for
|
||||
``__cause__`` makes it asymmetrical with ``__context__``.
|
||||
|
||||
|
||||
Proposal
|
||||
========
|
||||
|
||||
|
@ -62,6 +74,7 @@ To summarize, ``raise exc from cause`` will be equivalent to::
|
|||
where ``exc.__cause__ = cause`` implicitly sets
|
||||
``exc.__suppress_context__``.
|
||||
|
||||
|
||||
Patches
|
||||
=======
|
||||
|
||||
|
@ -74,6 +87,7 @@ References
|
|||
.. _issue 14133:
|
||||
http://bugs.python.org/issue14133
|
||||
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
|
|
170
pep-0420.txt
170
pep-0420.txt
|
@ -34,10 +34,12 @@ Within this PEP:
|
|||
* "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
|
||||
Python 3.2 and earlier.
|
||||
* "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".
|
||||
|
||||
|
@ -76,6 +78,10 @@ setuptools allows declaring namespace packages in a distribution's
|
|||
``setup.py``, so that distribution developers don't need to put the
|
||||
magic ``__path__`` modification into ``__init__.py`` themselves.
|
||||
|
||||
See PEP 402's "The Problem" section [2]_ for more details on the
|
||||
motivation for namespace packages. Note that PEP 402 has been
|
||||
rejected, but the motivating use cases are still valid.
|
||||
|
||||
Rationale
|
||||
=========
|
||||
|
||||
|
@ -135,48 +141,115 @@ If the scan completes without returning a module or package, and at
|
|||
least one directory was recorded, then a namespace package is created.
|
||||
The new namespace package:
|
||||
|
||||
* Has a ``__path__`` attribute set to the list of directories that
|
||||
were found and recorded during the scan.
|
||||
* Has a ``__path__`` attribute set to an iterable of the path strings
|
||||
that were found and recorded during the scan.
|
||||
|
||||
* Does not have a ``__file__`` attribute.
|
||||
|
||||
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
|
||||
``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
|
||||
deferred until a sub-level import occurs.
|
||||
|
||||
A namespace package is not fundamentally different from a regular
|
||||
package. It is just a different way of creating packages. Once a
|
||||
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).
|
||||
between it and a regular package.
|
||||
|
||||
Impact on Import Finders and Loaders
|
||||
Dynamic path computation
|
||||
------------------------
|
||||
|
||||
A namespace package's ``__path__`` will be recomputed if the value of
|
||||
the parent path changes. In order for this feature to work, the parent
|
||||
path must be modified in-place, not replaced with a new object. For
|
||||
example, for top-level namespace packages, this will work::
|
||||
|
||||
sys.path.append('new-dir')
|
||||
|
||||
But this will not::
|
||||
|
||||
sys.path = sys.path + ['new-dir']
|
||||
|
||||
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. This string must
|
||||
not contain a trailing path separator.
|
||||
These finders' ``find_module`` methods return either a "loader" object
|
||||
or ``None``.
|
||||
|
||||
For a finder to contribute to namespace packages, it must implement a
|
||||
new ``find_loader(fullname)`` method. ``fullname`` has the same
|
||||
meaning as for ``find_module``. ``find_loader`` always returns a
|
||||
2-tuple of ``(loader, <iterable-of-path-entries>)``. ``loader`` may
|
||||
be ``None``, in which case ``<iterable-of-path-entries>`` (which may
|
||||
be empty) is added to the list of recorded path entries and path
|
||||
searching continues. If ``loader`` is not ``None``, it is immediately
|
||||
used to load a module or regular package.
|
||||
|
||||
Even if ``loader`` is returned and is not ``None``,
|
||||
``<iterable-of-path-entries>`` must still contain the path entries for
|
||||
the package. This allows code such as ``pkgutil.extend_path()`` to
|
||||
compute path entries for packages that it does not load.
|
||||
|
||||
Note that multiple path entries per finder are allowed. This is to
|
||||
support the case where a finder discovers multiple namespace portions
|
||||
for a given ``fullname``. Many finders will support only a single
|
||||
namespace package portion per ``find_loader`` call, in which case this
|
||||
iterable will contain only a single string.
|
||||
|
||||
The import machinery will call ``find_loader`` if it exists, else fall
|
||||
back to ``find_module``. Legacy finders which implement
|
||||
``find_module`` but not ``find_loader`` will be unable to contribute
|
||||
portions to a namespace package.
|
||||
|
||||
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
|
||||
from ``find_module``, the only impact is that such a finder will be
|
||||
unable to provide portions of a namespace package.
|
||||
Differences between namespace packages and regular packages
|
||||
-----------------------------------------------------------
|
||||
|
||||
Namespace packages and regular packages are very similar. The
|
||||
differences are:
|
||||
|
||||
* Portions of namespace packages need not all come from the same
|
||||
directory structure, or even from the same loader. Regular packages
|
||||
are self-contained: all parts live in the same directory hierarchy.
|
||||
|
||||
* Namespace packages have no ``__file__`` attribute.
|
||||
|
||||
* Namespace packages' ``__path__`` attribute is a read-only iterable
|
||||
of strings, which is automatically updated when the parent path is
|
||||
modified.
|
||||
|
||||
* Namespace packages have no ``__init__.py`` module.
|
||||
|
||||
* Namespace packages have a different type of object for their
|
||||
``__loader__`` attribute.
|
||||
|
||||
|
||||
Namespace packages in the standard library
|
||||
------------------------------------------
|
||||
|
||||
It is possible, and this PEP explicitly allows, that parts of the
|
||||
standard library be implemented as namespace packages. When and if
|
||||
any standard library packages become namespace packages is outside the
|
||||
scope of this PEP.
|
||||
|
||||
|
||||
Migrating from legacy namespace packages
|
||||
----------------------------------------
|
||||
|
||||
As described above, prior to this PEP ``pkgutil.extend_path()`` was
|
||||
used by legacy portions to create namespace packages. Because it is
|
||||
likely not practical for all existing portions of a namespace package
|
||||
to be migrated to this PEP at once, ``extend_path()`` will be modified
|
||||
to also recognize PEP 420 namespace packages. This will allow some
|
||||
portions of a namespace to be legacy portions while others are
|
||||
migrated to PEP 420. These hybrid namespace packages will not have
|
||||
the dynamic path computation that normal namespace packages have,
|
||||
since ``extend_path()`` never provided this functionality in the past.
|
||||
|
||||
|
||||
Packaging Implications
|
||||
======================
|
||||
|
@ -201,7 +274,7 @@ 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
|
||||
corresponding "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.
|
||||
|
||||
It is also possible to have the "foo.bar" portion installed in a
|
||||
|
@ -212,7 +285,7 @@ Discussion
|
|||
==========
|
||||
|
||||
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]_.
|
||||
PEP 382 and PEP 402 were rejected, to be replaced by this PEP [3]_.
|
||||
|
||||
There is no intention to remove support of regular packages. If a
|
||||
developer knows that her package will never be a portion of a
|
||||
|
@ -227,7 +300,7 @@ lacking an ``__init__.py`` file. Such a directory will now be
|
|||
imported as a namespace package, whereas in prior Python versions an
|
||||
ImportWarning would be raised.
|
||||
|
||||
Nick Coghlan presented a list of his objections to this proposal [3]_.
|
||||
Nick Coghlan presented a list of his objections to this proposal [4]_.
|
||||
They are:
|
||||
|
||||
1. Implicit package directories go against the Zen of Python.
|
||||
|
@ -239,9 +312,9 @@ They are:
|
|||
layouts.
|
||||
|
||||
4. Implicit package directories will permanently entrench current
|
||||
newbie-hostile behaviour in ``__main__``.
|
||||
newbie-hostile behavior in ``__main__``.
|
||||
|
||||
Nick gave a detailed response [4]_, which is summarized here:
|
||||
Nick gave a detailed response [5]_, which is summarized here:
|
||||
|
||||
1. The practicality of this PEP wins over other proposals and the
|
||||
status quo.
|
||||
|
@ -253,11 +326,25 @@ Nick gave a detailed response [4]_, which is summarized here:
|
|||
|
||||
4. This will also be addressed in PEP 395.
|
||||
|
||||
Phillip Eby asked about auto-updating of ``__path__``, instead of it
|
||||
being a simple list [5]_. 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.
|
||||
``find_module`` versus ``find_loader``
|
||||
--------------------------------------
|
||||
|
||||
An early draft of this PEP specified a change to the ``find_module``
|
||||
method in order to support namespace packages. It would be modified
|
||||
to return a string in the case where a namespace package portion was
|
||||
discovered.
|
||||
|
||||
However, this caused a problem with existing code outside of the
|
||||
standard library which calls ``find_module``. Because this code would
|
||||
not be upgraded in concert with changes required by this PEP, it would
|
||||
fail when it would receive unexpected return values from
|
||||
``find_module``. Because of this incompatibility, this PEP now
|
||||
specifies that finders that want to provide namespace portions must
|
||||
implement the ``find_loader`` method, described above.
|
||||
|
||||
The use case for supporting multiple portions per ``find_loader`` call
|
||||
is given in [6]_.
|
||||
|
||||
|
||||
Module reprs
|
||||
============
|
||||
|
@ -304,17 +391,20 @@ References
|
|||
|
||||
.. [1] PEP 420 branch (http://hg.python.org/features/pep-420)
|
||||
|
||||
.. [2] PyCon 2012 Namespace Package discussion outcome
|
||||
.. [2] PEP 402's description of use cases for namespace packages
|
||||
(http://www.python.org/dev/peps/pep-0402/#the-problem)
|
||||
|
||||
.. [3] PyCon 2012 Namespace Package discussion outcome
|
||||
(http://mail.python.org/pipermail/import-sig/2012-March/000421.html)
|
||||
|
||||
.. [3] Nick Coghlan's objection to the lack of marker files or directories
|
||||
.. [4] Nick Coghlan's objection to the lack of marker files or directories
|
||||
(http://mail.python.org/pipermail/import-sig/2012-March/000423.html)
|
||||
|
||||
.. [4] Nick Coghlan's response to his initial objections
|
||||
.. [5] Nick Coghlan's response to his initial objections
|
||||
(http://mail.python.org/pipermail/import-sig/2012-April/000464.html)
|
||||
|
||||
.. [5] Phillip Eby's question about auto-updating __path__
|
||||
(http://mail.python.org/pipermail/import-sig/2012-April/000468.html)
|
||||
.. [6] Use case for multiple portions per ``find_loader`` call
|
||||
(http://mail.python.org/pipermail/import-sig/2012-May/000585.html)
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
|
431
pep-0421.txt
431
pep-0421.txt
|
@ -34,7 +34,7 @@ this change is due to the emergence of Jython, IronPython, and PyPy as
|
|||
viable alternate implementations of Python.
|
||||
|
||||
Consider, however, the nearly two decades of CPython-centric Python
|
||||
(i.e. most of its existence). That focus had understandably
|
||||
(i.e. most of its existence). That focus has understandably
|
||||
contributed to quite a few CPython-specific artifacts both in the
|
||||
standard library and exposed in the interpreter. Though the core
|
||||
developers have made an effort in recent years to address this, quite
|
||||
|
@ -51,41 +51,50 @@ Proposal
|
|||
========
|
||||
|
||||
We will add a new attribute to the ``sys`` module, called
|
||||
``sys.implementation``, as an instance of a new type to contain
|
||||
implementation-specific information.
|
||||
``sys.implementation``, as an object with attribute-access (as opposed
|
||||
to a mapping). It will contain contain implementation-specific
|
||||
information.
|
||||
|
||||
The attributes of this object will remain fixed during interpreter
|
||||
execution and through the course of an implementation version. This
|
||||
ensures behaviors don't change between versions which depend on
|
||||
variables in ``sys.implementation``.
|
||||
attributes of ``sys.implementation``.
|
||||
|
||||
The object will have each of the attributes described in the `Required
|
||||
Variables`_ section below. Any other per-implementation values may be
|
||||
stored in ``sys.implementation.metadata``. However, nothing in the
|
||||
standard library will rely on ``sys.implementation.metadata``.
|
||||
Examples of possible metadata values are described in the `Example
|
||||
Metadata Values`_ section.
|
||||
The object has each of the attributes described in the `Required
|
||||
Attributes`_ section below. Those attribute names will never start
|
||||
with an underscore. The standard library and the language definition
|
||||
will rely only on those required attributes.
|
||||
|
||||
This proposal takes a conservative approach in requiring only four
|
||||
variables. As more become appropriate, they may be added with
|
||||
discretion.
|
||||
This proposal takes a conservative approach in requiring only a small
|
||||
number of attributes. As more become appropriate, they may be added
|
||||
with discretion, as described in `Adding New Required Attributes`_.
|
||||
|
||||
While this PEP places no other constraints on ``sys.implementation``,
|
||||
it also recommends that no one rely on capabilities outside those
|
||||
described here. The only exception to that recommendation is for
|
||||
attributes starting with an underscore. Implementors may use those
|
||||
as appropriate to store per-implementation data.
|
||||
|
||||
|
||||
Required Variables
|
||||
------------------
|
||||
Required Attributes
|
||||
-------------------
|
||||
|
||||
These are variables in ``sys.implementation`` on which the standard
|
||||
library would rely, with the exception of ``metadata``, meaning
|
||||
implementers must define them:
|
||||
These are attributes in ``sys.implementation`` on which the standard
|
||||
library and language definition will rely, meaning implementers must
|
||||
define them:
|
||||
|
||||
**name**
|
||||
This is the common name of the implementation (case sensitive).
|
||||
Examples include 'PyPy', 'Jython', 'IronPython', and 'CPython'.
|
||||
A lower-case identifer representing the implementation. Examples
|
||||
include 'pypy', 'jython', 'ironpython', and 'cpython'.
|
||||
|
||||
**version**
|
||||
This is the version of the implementation, as opposed to the
|
||||
version of the language it implements. This value conforms to the
|
||||
format described in `Version Format`_.
|
||||
The version of the implementation, as opposed to the version of the
|
||||
language it implements. This value conforms to the format described
|
||||
in `Version Format`_.
|
||||
|
||||
**hexversion**
|
||||
The version of the implementation in the same hexadecimal format as
|
||||
``sys.hexversion``.
|
||||
|
||||
**cache_tag**
|
||||
A string used for the PEP 3147 cache tag [#cachetag]_. It would
|
||||
|
@ -94,17 +103,21 @@ implementers must define them:
|
|||
different cache tag. If ``cache_tag`` is set to None, it indicates
|
||||
that module caching should be disabled.
|
||||
|
||||
**metadata**
|
||||
Any other values that an implementation wishes to specify,
|
||||
particularly informational ones. Neither the standard library nor
|
||||
the language specification will rely on implementation metadata.
|
||||
Also see the list of `Example Metadata Values`_.
|
||||
|
||||
|
||||
Adding New Required Attributes
|
||||
------------------------------
|
||||
|
||||
XXX PEP? something lighter?
|
||||
In time more required attributes will be added to
|
||||
``sys.implementation``. However, each must have a meaningful use case
|
||||
across all Python implementations in order to be considered. This is
|
||||
made most clear by a use case in the standard library or language
|
||||
specification.
|
||||
|
||||
All proposals for new required attributes will go through the normal
|
||||
PEP process. Such a PEP need not be long, just long enough. It will
|
||||
need to sufficiently spell out the rationale for the new attribute,
|
||||
its use cases, and the impact it will have on the various Python
|
||||
implemenations.
|
||||
|
||||
|
||||
Version Format
|
||||
|
@ -112,59 +125,14 @@ Version Format
|
|||
|
||||
A main point of ``sys.implementation`` is to contain information that
|
||||
will be used internally in the standard library. In order to
|
||||
facilitate the usefulness of a version variable, its value should be
|
||||
in a consistent format across implementations.
|
||||
facilitate the usefulness of the version attribute, its value should
|
||||
be in a consistent format across implementations.
|
||||
|
||||
As such, the format of ``sys.implementation.version`` must follow that
|
||||
As such, the format of ``sys.implementation.version`` will follow that
|
||||
of ``sys.version_info``, which is effectively a named tuple. It is a
|
||||
familiar format and generally consistent with normal version format
|
||||
conventions.
|
||||
|
||||
XXX The following is not exactly true:
|
||||
|
||||
Keep in mind, however, that ``sys.implementation.version`` is the
|
||||
version of the Python *implementation*, while ``sys.version_info``
|
||||
(and friends) is the version of the Python language.
|
||||
|
||||
|
||||
Example Metadata Values
|
||||
-----------------------
|
||||
|
||||
These are the sorts of values an implementation may put into
|
||||
``sys.implementation.metadata``. However, these names and
|
||||
descriptions are only examples and are not being proposed here. If
|
||||
they later have meaningful uses cases, they can be added by following
|
||||
the process described in `Adding New Required Attributes`_.
|
||||
|
||||
**vcs_url**
|
||||
The URL pointing to the main VCS repository for the implementation
|
||||
project.
|
||||
|
||||
**vcs_revision_id**
|
||||
A value that identifies the VCS revision of the implementation that
|
||||
is currently running.
|
||||
|
||||
**build_toolchain**
|
||||
Identifies the tools used to build the interpreter.
|
||||
|
||||
**build_date**
|
||||
The timestamp of when the interpreter was built.
|
||||
|
||||
**homepage**
|
||||
The URL of the implementation's website.
|
||||
|
||||
**site_prefix**
|
||||
The preferred site prefix for this implementation.
|
||||
|
||||
**runtime**
|
||||
The run-time environment in which the interpreter is running, as
|
||||
in "Common Language *Runtime*" (.NET CLR) or "Java *Runtime*
|
||||
Executable".
|
||||
|
||||
**gc_type**
|
||||
The type of garbage collection used, like "reference counting" or
|
||||
"mark and sweep".
|
||||
|
||||
|
||||
Rationale
|
||||
=========
|
||||
|
@ -179,87 +147,41 @@ the implementation-specific information into a single namespace and
|
|||
makes explicit that which was implicit.
|
||||
|
||||
|
||||
Why a Custom Type?
|
||||
------------------
|
||||
Type Considerations
|
||||
-------------------
|
||||
|
||||
A dedicated class, of which ``sys.implementation`` is an instance, would
|
||||
facilitate the dotted access of a "named" tuple. At the same time, it
|
||||
allows us to avoid the problems of the other approaches (see below),
|
||||
like confusion about ordering and iteration.
|
||||
It's very easy to get bogged down in discussions about the type of
|
||||
``sys.implementation``. However, its purpose is to support the
|
||||
standard library and language definition. As such, there isn't much
|
||||
that really matters regarding its type, as opposed to a feature that
|
||||
would be more generally used. Thus characteristics like immutability
|
||||
and sequence-ness have been disregarded.
|
||||
|
||||
The alternatives to a dictionary are considered separately here:
|
||||
|
||||
**Dictionary**
|
||||
|
||||
A dictionary reflects a simple namespace with item access. It
|
||||
maps names to values and that's all. It also reflects the more variable
|
||||
nature of ``sys.implementation``.
|
||||
|
||||
However, a simple dictionary does not set expectations very well about
|
||||
the nature of ``sys.implementation``. The custom type approach, with
|
||||
a fixed set of required attributes, does a better job of this.
|
||||
|
||||
**Named Tuple**
|
||||
|
||||
Another close alternative is a namedtuple or a structseq or some other
|
||||
tuple type with dotted access (a la ``sys.version_info``). This type
|
||||
is immutable and simple. It is a well established pattern for
|
||||
implementation-specific variables in Python. Dotted access on a
|
||||
namespace is also very convenient.
|
||||
|
||||
Fallback lookup may favor dicts::
|
||||
|
||||
cache_tag = sys.implementation.get('cache_tag')
|
||||
|
||||
vs.
|
||||
|
||||
cache_tag = getattr(sys.implementation.get, 'cache_tag', None)
|
||||
|
||||
However, this is mitigated by having ``sys.implementation.metadata``.
|
||||
|
||||
One problem with using a named tuple is that ``sys.implementation`` does
|
||||
not have meaning as a sequence. Also, unlike other similar ``sys``
|
||||
variables, it has a far greater potential to change over time.
|
||||
|
||||
If a named tuple were used, we'd be very clear in the documentation
|
||||
that the length and order of the value are not reliable. Iterability
|
||||
would not be guaranteed.
|
||||
|
||||
**Module**
|
||||
|
||||
Using a module instead of a dict is another option. It has similar
|
||||
characteristics to an instance, but with a slight hint of immutability
|
||||
(at least by convention). Such a module could be a stand-alone sub-
|
||||
module of ``sys`` or added on, like ``os.path``. Unlike a concrete
|
||||
class, no new type would be necessary. This is a pretty close fit to
|
||||
what we need.
|
||||
|
||||
The downside is that the module type is much less conducive to
|
||||
extension, making it more difficult to address the weaknesses of using
|
||||
an instance of a concrete class.
|
||||
The only real choice has been between an object with attribute access
|
||||
and a mapping with item access. This PEP espouses dotted access to
|
||||
reflect the relatively fixed nature of the namespace.
|
||||
|
||||
|
||||
Why metadata?
|
||||
-------------
|
||||
Non-Required Attributes
|
||||
-----------------------
|
||||
|
||||
``sys.implementation.metadata`` will hold any optional, strictly-
|
||||
informational, or per-implementation data. This allows us to restrict
|
||||
``sys.implementation`` to the required attributes. In that way, its
|
||||
type can reflect the more stable namespace and
|
||||
``sys.implementation.metadata`` (as a dict) can reflect the less
|
||||
certain namespace.
|
||||
Earlier versions of this PEP included a required attribute called
|
||||
``metadata`` that held any non-required, per-implementation data
|
||||
[#Nick]_. However, this proved to be an unnecessary addition
|
||||
considering the purpose of ``sys.implementation``.
|
||||
|
||||
``sys.implementation.metadata`` is the place an implementation can put
|
||||
values that must be built-in, "without having to pollute the main sys
|
||||
namespace" [#Nick]_.
|
||||
Ultimately, non-required attributes are virtually ignored in this PEP.
|
||||
They have no impact other than that careless use may collide with
|
||||
future required attributes. That, however, is but a marginal concern
|
||||
for ``sys.implementation``.
|
||||
|
||||
|
||||
Why a Part of ``sys``?
|
||||
----------------------
|
||||
|
||||
The ``sys`` module should hold the new namespace because ``sys`` is
|
||||
the depot for interpreter-centric variables and functions. Many
|
||||
implementation-specific variables are already found in ``sys``.
|
||||
The ``sys`` module holds the new namespace because ``sys`` is the depot
|
||||
for interpreter-centric variables and functions. Many
|
||||
implementation-specific attributes are already found in ``sys``.
|
||||
|
||||
|
||||
Why Strict Constraints on Any of the Values?
|
||||
|
@ -269,7 +191,8 @@ As already noted in `Version Format`_, values in
|
|||
``sys.implementation`` are intended for use by the standard library.
|
||||
Constraining those values, essentially specifying an API for them,
|
||||
allows them to be used consistently, regardless of how they are
|
||||
otherwise implemented.
|
||||
otherwise implemented. However, care should be take to not
|
||||
over-specify the constraints.
|
||||
|
||||
|
||||
Discussion
|
||||
|
@ -281,6 +204,9 @@ revived the discussion recently while working on a pure-python
|
|||
``imp.get_tag()`` [#revived]_. Discussion has been ongoing
|
||||
[#feedback]_. The messages in `issue #14673`_ are also relevant.
|
||||
|
||||
A good part of the recent discussion centered on the type to use for
|
||||
``sys.implementation``.
|
||||
|
||||
|
||||
Use-cases
|
||||
=========
|
||||
|
@ -290,10 +216,10 @@ platform.python_implementation()
|
|||
|
||||
"explicit is better than implicit"
|
||||
|
||||
The ``platform`` module determines the python implementation by
|
||||
looking for clues in a couple different ``sys`` variables [#guess]_.
|
||||
However, this approach is fragile, requiring changes to the standard
|
||||
library each time an implementation changes. Beyond that, support in
|
||||
The ``platform`` module determines the python implementation by looking
|
||||
for clues in a couple different ``sys`` variables [#guess]_. However,
|
||||
this approach is fragile, requiring changes to the standard library
|
||||
each time an implementation changes. Beyond that, support in
|
||||
``platform`` is limited to those implementations that core developers
|
||||
have blessed by special-casing them in the ``platform`` module.
|
||||
|
||||
|
@ -302,7 +228,7 @@ With ``sys.implementation`` the various implementations would
|
|||
module.
|
||||
|
||||
Another concern is that the ``platform`` module is part of the stdlib,
|
||||
which ideally would minimize implementation details such as would be
|
||||
which ideally should minimize implementation details such as would be
|
||||
moved to ``sys.implementation``.
|
||||
|
||||
Any overlap between ``sys.implementation`` and the ``platform`` module
|
||||
|
@ -359,47 +285,108 @@ In Jython, ``os.name`` is set to 'java' to accommodate special
|
|||
treatment of the java environment in the standard library [#os_name]_
|
||||
[#javatest]_. Unfortunately it masks the os name that would otherwise
|
||||
go there. ``sys.implementation`` would help obviate the need for this
|
||||
special case.
|
||||
special case. Currently Jython sets ``os._name`` for the normal
|
||||
``os.name`` value.
|
||||
|
||||
|
||||
Feedback From Other Python Implementers
|
||||
The Problem With ``sys.(version|version_info|hexversion)``
|
||||
----------------------------------------------------------
|
||||
|
||||
Earlier versions of this PEP made the mistake of calling
|
||||
``sys.version_info`` (and friends) the version of the Python language,
|
||||
in contrast to the implementation. However, this is not the case.
|
||||
Instead, it is the version of the CPython implementation. Incidently,
|
||||
the first two components of ``sys.version_info`` (major and minor) also
|
||||
reflect the version of the language definition.
|
||||
|
||||
As Barry Warsaw noted, the "semantics of sys.version_info have been
|
||||
sufficiently squishy in the past" [#Barry]_. With
|
||||
``sys.implementation`` we have the opportunity to improve this
|
||||
situation by first establishing an explicit location for the version of
|
||||
the implementation.
|
||||
|
||||
This PEP makes no other effort to directly clarify the semantics of
|
||||
``sys.version_info``. Regardless, having an explicit version for the
|
||||
implementation will definitely help to clarify the distinction from the
|
||||
language version.
|
||||
|
||||
|
||||
Feedback From Other Python Implementors
|
||||
=======================================
|
||||
|
||||
IronPython
|
||||
----------
|
||||
|
||||
XXX
|
||||
Jeff Hardy responded to a request for feedback [#ironpython]_. He
|
||||
said, "I'll probably add it the day after it's approved"
|
||||
[#jeff_hardy_2012]_. He also gave useful feedback on both the type of
|
||||
``sys.implementation`` and on the ``metadata`` attribute (which has
|
||||
since been removed from the PEP).
|
||||
|
||||
Jython
|
||||
------
|
||||
|
||||
XXX
|
||||
In 2009 Frank Wierzbicki said this (relative to Jython implementing the
|
||||
required attributes) [#frank_wierzbicki_2009]_::
|
||||
|
||||
Speaking for Jython, so far it looks like something we would adopt
|
||||
soonish after it was accepted (it looks pretty useful to me).
|
||||
|
||||
PyPy
|
||||
----
|
||||
|
||||
XXX
|
||||
Some of the PyPy developers have responded to a request for feedback
|
||||
[#pypy]_. Armin Rigo said the following [#armin_rigo_2012]_::
|
||||
|
||||
For myself, I can only say that it looks like a good idea, which we
|
||||
will happily adhere to when we migrate to Python 3.3.
|
||||
|
||||
He also expressed support for keeping the required list small. Both
|
||||
Armin and Laura Creighton indicated that an effort to better catalog
|
||||
Python's implementation would be welcome. Such an effort, for which
|
||||
this PEP is a small start, will be considered separately.
|
||||
|
||||
|
||||
Past Efforts
|
||||
============
|
||||
|
||||
PEP 3139
|
||||
--------
|
||||
``PEP 3139``
|
||||
------------
|
||||
|
||||
This PEP from 2008 recommended a clean-up of the ``sys`` module in
|
||||
PEP 3139, from 2008, recommended a clean-up of the ``sys`` module in
|
||||
part by extracting implementation-specific variables and functions
|
||||
into a separate module. PEP 421 is a much lighter version of that
|
||||
into a separate module. PEP 421 is less ambitious version of that
|
||||
idea. While PEP 3139 was rejected, its goals are reflected in PEP 421
|
||||
to a large extent, though with a much lighter approach.
|
||||
|
||||
|
||||
PEP 399
|
||||
-------
|
||||
``PEP 399``
|
||||
-----------
|
||||
|
||||
This informational PEP dictates policy regarding the standard library,
|
||||
helping to make it friendlier to alternate implementations. PEP 421
|
||||
is proposed in that same spirit.
|
||||
PEP 399 dictates policy regarding the standard library, helping to make
|
||||
it friendlier to alternate implementations. PEP 421 is proposed in
|
||||
that same spirit.
|
||||
|
||||
|
||||
The Bigger Picture
|
||||
==================
|
||||
|
||||
It's worth noting again that this PEP is a small part of a larger
|
||||
on-going effort to identify the implementation-specific parts of Python
|
||||
and mitigate their impact on alternate implementations.
|
||||
|
||||
``sys.implementation`` is a focal point for implementation-specific
|
||||
data, acting as a nexus for cooperation between the language, the
|
||||
standard library, and the different implementations. As time goes by
|
||||
it is feasible that ``sys.implementation`` will assume current
|
||||
attributes of ``sys`` and other builtin/stdlib modules, where
|
||||
appropriate. In this way, it is a PEP 3137-lite, but starting as
|
||||
small as possible.
|
||||
|
||||
However, as already noted, many other efforts predate
|
||||
``sys.implementation``. Neither is it necessarily a major part of the
|
||||
effort. Rather, consider it as part of the infrastructure of the
|
||||
effort to make Python friendler to alternate implementations.
|
||||
|
||||
|
||||
Alternatives
|
||||
|
@ -409,50 +396,49 @@ Since the single-namespace-under-sys approach is relatively
|
|||
straightforward, no alternatives have been considered for this PEP.
|
||||
|
||||
|
||||
Examples of Other Attributes
|
||||
============================
|
||||
|
||||
These are examples only and not part of the proposal. Most of them
|
||||
were suggested during previous discussions, but did not fit into the
|
||||
goals of this PEP. (See `Adding New Required Attributes`_ if they get
|
||||
you excited.)
|
||||
|
||||
**common_name**
|
||||
The case-sensitive name by which the implementation is known.
|
||||
|
||||
**vcs_url**
|
||||
A URL for the main VCS repository for the implementation project.
|
||||
|
||||
**vcs_revision_id**
|
||||
A value that identifies the VCS revision of the implementation.
|
||||
|
||||
**build_toolchain**
|
||||
The tools used to build the interpreter.
|
||||
|
||||
**build_date**
|
||||
The timestamp of when the interpreter was built.
|
||||
|
||||
**homepage**
|
||||
The URL of the implementation's website.
|
||||
|
||||
**site_prefix**
|
||||
The preferred site prefix for the implementation.
|
||||
|
||||
**runtime**
|
||||
The run-time environment in which the interpreter is running, as
|
||||
in "Common Language *Runtime*" (.NET CLR) or "Java *Runtime*
|
||||
Executable".
|
||||
|
||||
**gc_type**
|
||||
The type of garbage collection used, like "reference counting" or
|
||||
"mark and sweep".
|
||||
|
||||
|
||||
Open Issues
|
||||
===========
|
||||
|
||||
* What are the long-term objectives for ``sys.implementation``?
|
||||
|
||||
- possibly pull in implementation details from the main ``sys``
|
||||
namespace and elsewhere (PEP 3137 lite).
|
||||
|
||||
* What is the process for introducing new required variables? PEP?
|
||||
|
||||
* Is the ``sys.version_info`` format the right one here?
|
||||
|
||||
* Should ``sys.implementation.hexversion`` be part of the PEP?
|
||||
|
||||
* Does ``sys.(version|version_info|hexversion)`` need to better
|
||||
reflect the version of the language spec? Micro version, series,
|
||||
and release seem like implementation-specific values.
|
||||
|
||||
* Alternatives to the approach dictated by this PEP?
|
||||
|
||||
* Do we really want to commit to using a dict for
|
||||
``sys.implementation``?
|
||||
|
||||
Backward compatibility issues will make it difficult to change our
|
||||
minds later.
|
||||
|
||||
The type we use ultimately depends on how general we expect the
|
||||
consumption of ``sys.implementation`` to be. If its practicality is
|
||||
oriented toward internal use then the data structure is not as
|
||||
critical. However, ``sys.implementation`` is intended to have a
|
||||
non-localized impact across the standard library and the
|
||||
interpreter. It is better to *not* make hacking it become an
|
||||
attractive nuisance, regardless of our intentions for usage.
|
||||
|
||||
* Should ``sys.implementation`` and its values be immutable? A benefit
|
||||
of an immutable type is it communicates that the value is not
|
||||
expected to change and should not be manipulated.
|
||||
|
||||
* Should ``sys.implementation`` be strictly disallowed to have methods?
|
||||
Classes often imply the presence (or possibility) of methods, which
|
||||
may be misleading in this case.
|
||||
|
||||
* Should ``sys.implementation`` implement the collections.abc.Mapping
|
||||
interface?
|
||||
Currently none.
|
||||
|
||||
|
||||
Implementation
|
||||
|
@ -468,11 +454,33 @@ References
|
|||
http://mail.python.org/pipermail/python-dev/2009-October/092893.html
|
||||
|
||||
.. [#revived] The initial 2012 discussion:
|
||||
http://mail.python.org/pipermail/python-ideas/2012-April/014878.html
|
||||
http://mail.python.org/pipermail/python-ideas/2012-March/014555.html
|
||||
(and http://mail.python.org/pipermail/python-ideas/2012-April/014878.html)
|
||||
|
||||
.. [#feedback] Feedback on the PEP:
|
||||
http://mail.python.org/pipermail/python-ideas/2012-April/014954.html
|
||||
|
||||
.. [#ironpython] Feedback from the IronPython developers:
|
||||
http://mail.python.org/pipermail/ironpython-users/2012-May/015980.html
|
||||
|
||||
.. [#dino_viehland_2009] (2009) Dino Viehland offers his opinion:
|
||||
http://mail.python.org/pipermail/python-dev/2009-October/092894.html
|
||||
|
||||
.. [#jeff_hardy_2012] (2012) Jeff Hardy offers his opinion:
|
||||
http://mail.python.org/pipermail/ironpython-users/2012-May/015981.html
|
||||
|
||||
.. [#jython] Feedback from the Jython developers:
|
||||
???
|
||||
|
||||
.. [#frank_wierzbicki_2009] (2009) Frank Wierzbicki offers his opinion:
|
||||
http://mail.python.org/pipermail/python-dev/2009-October/092974.html
|
||||
|
||||
.. [#pypy] Feedback from the PyPy developers:
|
||||
http://mail.python.org/pipermail/pypy-dev/2012-May/009883.html
|
||||
|
||||
.. [#armin_rigo_2012] (2012) Armin Rigo offers his opinion:
|
||||
http://mail.python.org/pipermail/pypy-dev/2012-May/009884.html
|
||||
|
||||
.. [#guess] The ``platform`` code which divines the implementation name:
|
||||
http://hg.python.org/cpython/file/2f563908ebc5/Lib/platform.py#l1247
|
||||
|
||||
|
@ -497,6 +505,9 @@ References
|
|||
.. [#Nick] Nick Coghlan's proposal for ``sys.implementation.metadata``:
|
||||
http://mail.python.org/pipermail/python-ideas/2012-May/014984.html
|
||||
|
||||
.. [#Barry] Feedback from Barry Warsaw:
|
||||
http://mail.python.org/pipermail/python-dev/2012-May/119374.html
|
||||
|
||||
.. _issue #14673: http://bugs.python.org/issue14673
|
||||
|
||||
.. _Lib/test/support.py: http://hg.python.org/cpython/file/2f563908ebc5/Lib/test/support.py
|
||||
|
|
43
pep-3144.txt
43
pep-3144.txt
|
@ -5,30 +5,36 @@ Last-Modified: $Date$
|
|||
Author: Peter Moody <pmoody@google.com>
|
||||
BDFL-Delegate: Nick Coghlan
|
||||
Discussions-To: <ipaddr-py-dev@googlegroups.com>
|
||||
Status: Draft
|
||||
Status: Accepted
|
||||
Type: Standards Track
|
||||
Content-Type: text/plain
|
||||
Created: 6-Feb-2012
|
||||
Python-Version: 3.3
|
||||
|
||||
Resolution: http://mail.python.org/pipermail/python-dev/2012-May/119474.html
|
||||
|
||||
Abstract:
|
||||
|
||||
This PEP proposes a design and for an IP address manipulation module for
|
||||
python.
|
||||
|
||||
|
||||
PEP Acceptance:
|
||||
|
||||
This PEP was accepted by Nick Coghlan on the 15th of May, 2012.
|
||||
|
||||
|
||||
Motivation:
|
||||
|
||||
Several very good IP address modules for python already exist.
|
||||
The truth is that all of the struggle with the balance between
|
||||
The truth is that all of them struggle with the balance between
|
||||
adherence to Pythonic principals and the shorthand upon which
|
||||
network engineers and administrators rely. I believe ipaddr
|
||||
strikes the right balance.
|
||||
network engineers and administrators rely. ipaddress aims to
|
||||
strike the right balance.
|
||||
|
||||
|
||||
Rationale:
|
||||
|
||||
The existance of several Python IP address manipulation moduels is
|
||||
The existence of several Python IP address manipulation modules is
|
||||
evidence of an outstanding need for the functionality this module
|
||||
seeks to provide.
|
||||
|
||||
|
@ -55,6 +61,23 @@ Background:
|
|||
* A few attributes were renamed to disambiguate their purpose as
|
||||
well. (eg. network, network_address)
|
||||
|
||||
* A number of methods and functions which returned containers in ipaddr now
|
||||
return iterators. This includes, subnets, address_exclude,
|
||||
summarize_address_range and collapse_address_list.
|
||||
|
||||
|
||||
Due to the backwards incompatible API changes between ipaddress and ipaddr,
|
||||
the proposal is to add the module using the new provisional API status:
|
||||
|
||||
* http://docs.python.org/dev/glossary.html#term-provisional-package
|
||||
|
||||
|
||||
Relevant messages on python-dev:
|
||||
|
||||
* http://mail.python.org/pipermail/python-dev/2012-January/116016.html
|
||||
* http://mail.python.org/pipermail/python-dev/2012-February/116656.html
|
||||
* http://mail.python.org/pipermail/python-dev/2012-February/116688.html
|
||||
|
||||
|
||||
Specification:
|
||||
|
||||
|
@ -101,8 +124,7 @@ Specification:
|
|||
_BaseV4 - Provides methods and variables (eg, _max_prefixlen)
|
||||
common to all IPv4 classes.
|
||||
|
||||
_BaseV6 - Provides methods and variables common to all IPv6
|
||||
classes.
|
||||
_BaseV6 - Provides methods and variables common to all IPv6 classes.
|
||||
|
||||
Comparisons between objects of differing IP versions results in a
|
||||
TypeError [1]. Additionally, comparisons of objects with
|
||||
|
@ -115,7 +137,10 @@ Specification:
|
|||
Reference Implementation:
|
||||
|
||||
The current reference implementation can be found at:
|
||||
http://code.google.com/p/ipaddr-py/downloads/detail?name=3144.tar.gz
|
||||
http://code.google.com/p/ipaddress-py/source/browse/ipaddress.py
|
||||
|
||||
Or see the tarball to include the README and unittests.
|
||||
http://code.google.com/p/ipaddress-py/downloads/detail?name=ipaddress-1.0.tar.gz
|
||||
|
||||
More information about using the reference implementation can be
|
||||
found at: http://code.google.com/p/ipaddr-py/wiki/Using3144
|
||||
|
|
Loading…
Reference in New Issue