Eric's latest update
This commit is contained in:
parent
b7a0f00a30
commit
5b80ee6d1d
327
pep-0421.txt
327
pep-0421.txt
|
@ -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.
|
||||
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,19 +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`_. ``metadata`` is a
|
||||
dictionary. While a mutable type, neither it nor its items will
|
||||
change (as already noted). Likewise they should not be modified.
|
||||
|
||||
|
||||
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 all that long, but 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
|
||||
|
@ -114,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
|
||||
=========
|
||||
|
@ -181,79 +147,33 @@ 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 in this regard, 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 was 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``?
|
||||
|
@ -261,7 +181,7 @@ 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``.
|
||||
implementation-specific attributes are already found in ``sys``.
|
||||
|
||||
|
||||
Why Strict Constraints on Any of the Values?
|
||||
|
@ -271,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
|
||||
|
@ -283,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 discussion centered on the type to use for
|
||||
``sys.implementation``.
|
||||
|
||||
|
||||
Use-cases
|
||||
=========
|
||||
|
@ -361,8 +285,30 @@ 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. Currently Jython sets os._name for the normal os.name
|
||||
value.
|
||||
special case. Currently Jython sets ``os._name`` for the normal
|
||||
``os.name`` value.
|
||||
|
||||
|
||||
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 improving the
|
||||
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
|
||||
|
@ -395,9 +341,9 @@ Some of the PyPy developers have responded to a request for feedback
|
|||
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 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.
|
||||
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
|
||||
|
@ -408,7 +354,7 @@ PEP 3139
|
|||
|
||||
This PEP 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.
|
||||
|
||||
|
@ -449,43 +395,47 @@ 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. (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 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.
|
||||
|
||||
* 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
|
||||
|
@ -552,6 +502,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
|
||||
|
|
Loading…
Reference in New Issue