Eric's latest update

This commit is contained in:
Barry Warsaw 2012-05-12 07:27:18 -07:00
parent b7a0f00a30
commit 5b80ee6d1d
1 changed files with 140 additions and 187 deletions

View File

@ -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