[Python-checkins] peps: Major update to metadata 2.0 draft specs

nick.coghlan python-checkins at python.org
Sat Dec 21 14:52:15 CET 2013


http://hg.python.org/peps/rev/d18629859154
changeset:   5333:d18629859154
user:        Nick Coghlan <ncoghlan at gmail.com>
date:        Sat Dec 21 23:52:04 2013 +1000
summary:
  Major update to metadata 2.0 draft specs

- split many fields out to standard extensions
- support for local versions in PEP 440
- addressed several other issues noted in
  https://bitbucket.org/pypa/pypi-metadata-formats/issues

files:
  pep-0426.txt |  953 ++++++++------------------------------
  pep-0440.txt |  248 ++++++++-
  pep-0459.txt |   35 +-
  3 files changed, 434 insertions(+), 802 deletions(-)


diff --git a/pep-0426.txt b/pep-0426.txt
--- a/pep-0426.txt
+++ b/pep-0426.txt
@@ -13,7 +13,8 @@
 Requires: 440
 Created: 30 Aug 2012
 Post-History: 14 Nov 2012, 5 Feb 2013, 7 Feb 2013, 9 Feb 2013,
-              27 May 2013, 20 Jun 2013, 23 Jun 2013, 14 Jul 2013
+              27 May 2013, 20 Jun 2013, 23 Jun 2013, 14 Jul 2013,
+              21 Dec 2013
 Replaces: 345
 
 
@@ -62,16 +63,14 @@
 
    * this PEP, covering the core metadata format
    * PEP 440, covering the versioning identification and selection scheme
-   * a new PEP to define v2.0 of the sdist format
+   * PEP 459, covering several standard extensions
+   * a yet-to-be-written PEP to define v2.0 of the sdist format
    * an updated wheel PEP (v1.1) to add pydist.json (and possibly convert
      the wheel metadata file from Key:Value to JSON)
-   * an updated installation database PEP both for pydist.json (and possibly convert
-     the wheel metadata file from Key:Value to JSON)
-   * an alternative to \*.pth files that avoids system global side effects
-     and better supports runtime selection of dependencies
-   * a new static config PEP to standardise metadata generation and
-     creation of sdists
-   * a PEP to cover bundling ``pip`` with the CPython installers
+   * an updated installation database PEP to add pydist.json
+   * a PEP to standardise the expected command line interface for setup.py
+     as an interface to an application's build system (rather than requiring
+     that the build system support the distutils command system)
 
    It's going to take a while to work through all of these and make them
    a reality. The main change from our last attempt at this is that we're
@@ -87,23 +86,6 @@
    an irrelevant distraction for future readers.
 
 
-A Note on Time Frames
-=====================
-
-There's a lot of work going on in the Python packaging space at the moment.
-In the near term (up until the release of Python 3.4), those efforts will be
-focused on the existing metadata standards, both those defined in Python
-Enhancement Proposals, and the de facto standards defined by the setuptools
-project.
-
-This PEP is about setting out a longer term goal for the ecosystem that
-captures those existing capabilities in a format that is easier to work
-with. There are still a number of key open questions (mostly related to
-source based distribution), and those won't be able to receive proper
-attention from the development community until the other near term
-concerns have been resolved.
-
-
 Purpose
 =======
 
@@ -114,7 +96,9 @@
 Python code by those doing the analysis. Another aim is to encourage good
 software distribution practices by default, while continuing to support the
 current practices of almost all existing users of the Python Package Index
-(both publishers and integrators).
+(both publishers and integrators). Finally, the aim is to support an upgrade
+path from the existing setuptools defined dependency and entry point
+metadata formats that is transparent to end users.
 
 The design draws on the Python community's 15 years of experience with
 distutils based software distribution, and incorporates ideas and concepts
@@ -122,6 +106,36 @@
 other projects, Ruby's gems, Perl's CPAN, Node.js's npm, PHP's composer
 and Linux packaging systems such as RPM and APT.
 
+While the specifics of this format are aimed at the Python ecosystem, some
+of the ideas may also be useful in the future evolution of other dependency
+management ecosystems.
+
+
+A Note on Time Frames
+=====================
+
+There's a lot of work going on in the Python packaging space at the moment.
+In the near term (up until the release of Python 3.4), those efforts are
+focused on the existing metadata standards, both those defined in Python
+Enhancement Proposals, and the de facto standards defined by the setuptools
+project.
+
+This PEP is about setting out a longer term goal for the ecosystem that
+captures those existing capabilities in a format that is easier to work
+with. There are still a number of key open questions (mostly related to
+source based distribution), and those won't be able to receive proper
+attention from the development community until the other near term
+concerns have been resolved.
+
+At this point in time, the PEP is quite possibly still overengineered, as
+we're still trying to make sure we have all the use cases covered. The
+"transparent upgrade path from setuptools" goal brings in a lot of required
+functionality though, and then the aim of supporting automated creation of
+policy compliant downstream packages for Linux distributions adds more.
+However, we've at least reached the point where we're taking a critical
+look at the core metadata, and are pushing as much functionality out to
+standard metadata extensions as we can.
+
 
 Development, Distribution and Deployment of Python Software
 ===========================================================
@@ -138,8 +152,8 @@
 
 * Software publication: this phase involves taking the developed software
   and making it available for use by software integrators. This includes
-  creating the descriptive metadata defined in this PEP, as well making the
-  software available (typically by uploading it to an index server).
+  creating the descriptive metadata defined in this PEP, as well as making
+  the software available (typically by uploading it to an index server).
 
 * Software integration: this phase involves taking published software
   components and combining them into a coherent, integrated system. This
@@ -153,7 +167,9 @@
 
 The publication and integration phases are collectively referred to as
 the distribution phase, and the individual software components distributed
-in that phase are referred to as "distributions".
+in that phase are formally referred to as "distributions", but are more
+colloquially known as "packages" (relying on context to disambiguate them
+from the "module with submodules" kind of Python package).
 
 The exact details of these phases will vary greatly for particular use cases.
 Deploying a web application to a public Platform-as-a-Service provider,
@@ -185,6 +201,10 @@
 "Distributions" are the packaged files which are used to publish
 and distribute a release.
 
+Depending on context, "package" may refer to either a distribution, or
+to an importable Python module that has a ``__path__`` attribute and hence
+may also have importable submodules.
+
 "Source archive" and "VCS checkout" both refer to the raw source code for
 a release, prior to creation of an sdist or binary archive.
 
@@ -419,7 +439,9 @@
 metadata.
 
 Each metadata file consists of a single serialised mapping, with fields as
-described in this PEP.
+described in this PEP. When serialising metadata, automated tools SHOULD
+lexically sort any keys and list elements in order to simplify reviews
+of any changes.
 
 There are three standard locations for these metadata files:
 
@@ -457,91 +479,6 @@
 in Appendix A.
 
 
-Essential dependency resolution metadata
-----------------------------------------
-
-For dependency resolution purposes, it is useful to have a minimal subset
-of the metadata that contains only those fields needed to identify
-distributions and resolve dependencies between them.
-
-The essential dependency resolution metadata consists of the following
-fields:
-
-* ``metadata_version``
-* ``generator``
-* ``name``
-* ``version``
-* ``source_label``
-* ``source_url``
-* ``extras``
-* ``meta_requires``
-* ``run_requires``
-* ``test_requires``
-* ``build_requires``
-* ``dev_requires``
-* ``provides``
-* ``obsoleted_by``
-* ``supports_environments``
-
-When serialised to a file, the name used for this metadata set SHOULD
-be ``pydist-dependencies.json``.
-
-
-Export metadata
----------------
-
-Distributions may define components that are intended for use by other
-distributions (such as plugins). As it can be beneficial to know whether or
-not a distribution defines any such exports without needing to parse any
-metadata, a suitable subset is defined for serialisation to a separate file
-in the ``dist-info`` metadata directory.
-
-The external command metadata consists of the following fields:
-
-* ``metadata_version``
-* ``generator``
-* ``name``
-* ``version``
-* ``exports``
-
-When serialised to a file, the name used for this metadata set SHOULD
-be ``pydist-exports.json``.
-
-
-Command metadata
-----------------
-
-Distributions may define commands that will be available from the command
-line following installation. As it can be beneficial to know whether or not
-a distribution has such commands without needing to parse any metadata,
-a suitable subset is defined for serialisation to a separate file in the
-``dist-info`` metadata directory.
-
-The external command metadata consists of the following fields:
-
-* ``metadata_version``
-* ``generator``
-* ``name``
-* ``version``
-* ``commands``
-
-When serialised to a file, the name used for this metadata set SHOULD
-be ``pydist-commands.json``.
-
-
-Included documents
-------------------
-
-Rather than being incorporated directly into the structured metadata, some
-supporting documents are included alongside the metadata file in the
-``dist-info`` metadata directory.
-
-To accommodate the variety of existing naming conventions for these files,
-they are explicitly identified in the ``document_names`` field, rather
-than expecting index servers and other automated tools to identify them
-automatically.
-
-
 Metadata validation
 -------------------
 
@@ -555,6 +492,12 @@
 Except where otherwise noted, all URL fields in the metadata MUST comply
 with RFC 3986.
 
+.. note::
+
+   The current version of the schema file covers the previous draft of the
+   PEP, and has not yet been updated for the split into the essential
+   dependency resolution metadata and multiple standard extensions.
+
 
 Core metadata
 =============
@@ -678,7 +621,8 @@
 This field SHOULD NOT contain any line breaks.
 
 A more complete description SHOULD be included as a separate file in the
-sdist for the distribution. See `Document names`_ for details.
+sdist for the distribution. Refer to the ``python-details`` extension in
+:pep:`459` for more information.
 
 Example::
 
@@ -734,13 +678,14 @@
 suitable VCS checkout. It is intended primarily for integrators that
 wish to recreate the distribution from the original source form.
 
-All source URL references SHOULD specify a secure transport
-mechanism (such as ``https``), include an expected hash value in the
-URL for verification purposes, or both. If an insecure transport is specified
-without any hash information, with hash information that the tool doesn't
-understand, or with a selected hash algorithm that the tool considers too
-weak to trust, automated tools SHOULD at least emit a warning and MAY
-refuse to rely on the URL.
+All source URL references SHOULD specify a secure transport mechanism
+(such as ``https``) AND include an expected hash value in the URL for
+verification purposes. If a source URL is specified without any hash
+information, with hash information that the tool doesn't understand, or
+with a selected hash algorithm that the tool considers too weak to trust,
+automated tools SHOULD at least emit a warning and MAY refuse to rely on
+the URL. If such a source URL also uses an insecure transport, automated
+tools SHOULD NOT rely on the URL.
 
 It is RECOMMENDED that only hashes which are unconditionally provided by
 the latest version of the standard library's ``hashlib`` module be used
@@ -753,236 +698,31 @@
 fragment.
 
 For version control references, the ``VCS+protocol`` scheme SHOULD be
-used to identify both the version control system and the secure transport.
-
-To support version control systems that do not support including commit or
+used to identify both the version control system and the secure transport,
+and a version control system with hash based commit identifiers SHOULD be
+used. Automated tools MAY omit warnings about missing hashes for version
+control systems that do not provide hash based commit identifiers.
+
+To handle version control systems that do not support including commit or
 tag references directly in the URL, that information may be appended to the
-end of the URL using the ``@<tag>`` notation.
+end of the URL using the ``@<commit-hash>`` or the ``@<tag>#<commit-hash>``
+notation.
+
+.. note::
+
+   This isn't *quite* the same as the existing VCS reference notation
+   supported by pip. Firstly, the distribution name is moved in front rather
+   than embedded as part of the URL. Secondly, the commit hash is included
+   even when retrieving based on a tag, in order to meet the requirement
+   above that *every* link should include a hash to make things harder to
+   forge (creating a malicious repo with a particular tag is easy, creating
+   one with a specific *hash*, less so).
 
 Example::
 
-    "source_url": "https://github.com/pypa/pip/archive/1.3.1.zip"
-    "source_url": "http://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686"
-    "source_url": "git+https://github.com/pypa/pip.git@1.3.1"
-
-
-Additional descriptive metadata
-===============================
-
-This section specifies fields that provide additional information regarding
-the distribution and its contents.
-
-All of these fields are optional. Automated tools MUST operate correctly if
-a distribution does not provide them, including failing cleanly when an
-operation depending on one of these fields is requested.
-
-
-License
--------
-
-A short string summarising the license used for this distribution.
-
-Note that distributions that provide this field should still specify any
-applicable license Trove classifiers in the `Classifiers`_ field. Even
-when an appropriate Trove classifier is available, the license summary can
-be a good way to specify a particular version of that license, or to
-indicate any variations or exception to the license.
-
-This field SHOULD contain fewer than 512 characters and MUST contain fewer
-than 2048.
-
-This field SHOULD NOT contain any line breaks.
-
-The full license text SHOULD be included as a separate file in the source
-archive for the distribution. See `Document names`_ for details.
-
-Example::
-
-    "license": "GPL version 3, excluding DRM provisions"
-
-
-Keywords
---------
-
-A list of additional keywords to be used to assist searching for the
-distribution in a larger catalog.
-
-Example::
-
-    "keywords": ["comfy", "chair", "cushions", "too silly", "monty python"]
-
-
-Classifiers
------------
-
-A list of strings, with each giving a single classification value
-for the distribution.  Classifiers are described in PEP 301 [2].
-
-Example::
-
-    "classifiers": [
-      "Development Status :: 4 - Beta",
-      "Environment :: Console (Text Based)",
-      "License :: OSI Approved :: GNU General Public License v3 (GPLv3)"
-    ]
-
-
-Document names
---------------
-
-Filenames for supporting documents included in the distribution's
-``dist-info`` metadata directory.
-
-The following supporting documents can be named:
-
-* ``description``: a file containing a long description of the distribution
-* ``license``: a file with the full text of the distribution's license
-* ``changelog``: a file describing changes made to the distribution
-
-Supporting documents MUST be included directly in the ``dist-info``
-directory. Directory separators are NOT permitted in document names.
-
-The markup format (if any) for the file is indicated by the file extension.
-This allows index servers and other automated tools to render included
-text documents correctly and provide feedback on rendering errors, rather
-than having to guess the intended format.
-
-If the filename has no extension, or the extension is not recognised, the
-default rendering format MUST be plain text.
-
-The following markup renderers SHOULD be used for the specified file
-extensions:
-
-* Plain text: ``.txt``, no extension, unknown extension
-* reStructured Text: ``.rst``
-* Markdown: ``.md``
-* AsciiDoc: ``.adoc``, ``.asc``, ``.asciidoc``
-* HTML: ``.html``, ``.htm``
-
-Automated tools MAY render one or more of the specified formats as plain
-text and MAY render other markup formats beyond those listed.
-
-Automated tools SHOULD NOT make any assumptions regarding the maximum length
-of supporting document content, except as necessary to protect the
-integrity of a service.
-
-Example::
-
-    "document_names": {
-        "description": "README.rst",
-        "license": "LICENSE.rst",
-        "changelog": "NEWS"
-    }
-
-
-Contributor metadata
-====================
-
-Contributor metadata for a distribution is provided to allow users to get
-access to more information about the distribution and its maintainers.
-
-These details are recorded as mappings with the following subfields:
-
-* ``name``: the name of an individual or group
-* ``email``: an email address (this may be a mailing list)
-* ``url``: a URL (such as a profile page on a source code hosting service)
-* ``role``: one of ``"author"``, ``"maintainer"`` or ``"contributor"``
-
-The ``name`` subfield is required, the other subfields are optional.
-
-If no specific role is stated, the default is ``contributor``.
-
-Email addresses must be in the form ``local-part at domain`` where the
-local-part may be up to 64 characters long and the entire email address
-contains no more than 254 characters. The formal specification of the
-format is in RFC 5322 (sections 3.2.3 and 3.4.1) and RFC 5321, with a more
-readable form given in the informational RFC 3696 and the associated errata.
-
-The defined contributor roles are as follows:
-
-* ``author``: the original creator of a distribution
-* ``maintainer``: the current lead contributor for a distribution, when
-  they are not the original creator
-* ``contributor``: any other individuals or organizations involved in the
-  creation of the distribution
-
-Contact and contributor metadata is optional. Automated tools MUST operate
-correctly if a distribution does not provide it, including failing cleanly
-when an operation depending on one of these fields is requested.
-
-
-Contacts
---------
-
-A list of contributor entries giving the recommended contact points for
-getting more information about the project.
-
-The example below would be suitable for a project that was in the process
-of handing over from the original author to a new lead maintainer, while
-operating as part of a larger development group.
-
-Example::
-
-    "contacts": [
-      {
-        "name": "Python Packaging Authority/Distutils-SIG",
-        "email": "distutils-sig at python.org",
-        "url": "https://bitbucket.org/pypa/"
-      },
-      {
-        "name": "Samantha C.",
-        "role": "maintainer",
-        "email": "dontblameme at example.org"
-      },
-      {
-        "name": "Charlotte C.",
-        "role": "author",
-        "email": "iambecomingasketchcomedian at example.com"
-      }
-    ]
-
-
-Contributors
-------------
-
-A list of contributor entries for other contributors not already listed as
-current project points of contact. The subfields within the list elements
-are the same as those for the main contact field.
-
-Example::
-
-    "contributors": [
-      {"name": "John C."},
-      {"name": "Erik I."},
-      {"name": "Terry G."},
-      {"name": "Mike P."},
-      {"name": "Graeme C."},
-      {"name": "Terry J."}
-    ]
-
-
-Project URLs
-------------
-
-A mapping of arbitrary text labels to additional URLs relevant to the
-project.
-
-While projects are free to choose their own labels and specific URLs,
-it is RECOMMENDED that home page, source control, issue tracker and
-documentation links be provided using the labels in the example below.
-
-URL labels MUST be treated as case insensitive by automated tools, but they
-are not required to be valid Python identifiers. Any legal JSON string is
-permitted as a URL label.
-
-Example::
-
-    "project_urls": {
-      "Documentation": "https://distlib.readthedocs.org"
-      "Home": "https://bitbucket.org/pypa/distlib"
-      "Repository": "https://bitbucket.org/pypa/distlib/src"
-      "Tracker": "https://bitbucket.org/pypa/distlib/issues"
-    }
+    "source_url": "https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686"
+    "source_url": "git+https://github.com/pypa/pip.git@1.3.1#7921be1537eac1e97bc40179a57f0349c2aee67d"
+    "source_url": "git+https://github.com/pypa/pip.git@7921be1537eac1e97bc40179a57f0349c2aee67d"
 
 
 Semantic dependencies
@@ -1001,10 +741,10 @@
 
 Distributions may declare five differents kinds of dependency:
 
+* Runtime dependencies: other distributions that are needed to actually use
+  this distribution (but are not considered subdistributions).
 * "Meta" dependencies: subdistributions that are grouped together into a
   single larger metadistribution for ease of reference and installation.
-* Runtime dependencies: other distributions that are needed to actually use
-  this distribution (but are not considered subdistributions).
 * Test dependencies: other distributions that are needed to run the
   automated test suite for this distribution (but are not needed just to
   use it).
@@ -1105,24 +845,24 @@
 
 * Implied runtime dependencies:
 
+    * ``run_requires``
     * ``meta_requires``
-    * ``run_requires``
 
 * Implied build dependencies:
 
     * ``build_requires``
     * If running the distribution's test suite as part of the build process,
-      request the ``:meta:``, ``:run:`` and ``:test:`` extras to also
+      request the ``:run:``, ``:meta:``, and ``:test:`` extras to also
       install:
 
+      * ``run_requires``
       * ``meta_requires``
-      * ``run_requires``
       * ``test_requires``
 
 * Implied development and publication dependencies:
 
+    * ``run_requires``
     * ``meta_requires``
-    * ``run_requires``
     * ``build_requires``
     * ``test_requires``
     * ``dev_requires``
@@ -1153,6 +893,32 @@
     "extras": ["warmup"]
 
 
+Run requires
+------------
+
+A list of other distributions needed to actually run this distribution.
+
+Automated tools MUST NOT allow strict version matching clauses or direct
+references in this field - if permitted at all, such clauses should appear
+in ``meta_requires`` instead.
+
+Example::
+
+    "run_requires":
+      {
+        "requires": ["SciPy", "PasteDeploy", "zope.interface (>3.5.0)"]
+      },
+      {
+        "requires": ["pywin32 (>1.0)"],
+        "environment": "sys_platform == 'win32'"
+      },
+      {
+        "requires": ["SoftCushions"],
+        "extra": "warmup"
+      }
+    ]
+
+
 Meta requires
 -------------
 
@@ -1183,33 +949,7 @@
       },
       {
         "requires": ["CupOfTeaAtEleven (== 1.0a2)"],
-        "environment": "'linux' in sys.platform"
-      }
-    ]
-
-
-Run requires
-------------
-
-A list of other distributions needed to actually run this distribution.
-
-Automated tools MUST NOT allow strict version matching clauses or direct
-references in this field - if permitted at all, such clauses should appear
-in ``meta_requires`` instead.
-
-Example::
-
-    "run_requires":
-      {
-        "requires": ["SciPy", "PasteDeploy", "zope.interface (>3.5.0)"]
-      },
-      {
-        "requires": ["pywin32 (>1.0)"],
-        "environment": "sys.platform == 'win32'"
-      },
-      {
-        "requires": ["SoftCushions"],
-        "extra": "warmup"
+        "environment": "'linux' in sys_platform"
       }
     ]
 
@@ -1234,7 +974,7 @@
       },
       {
         "requires": ["pywin32 (>1.0)"],
-        "environment": "sys.platform == 'win32'"
+        "environment": "sys_platform == 'win32'"
       },
       {
         "requires": ["CompressPadding"],
@@ -1266,7 +1006,7 @@
       },
       {
         "requires": ["pywin32 (>1.0)"],
-        "environment": "sys.platform == 'win32'"
+        "environment": "sys_platform == 'win32'"
       },
       {
         "requires": ["cython"],
@@ -1302,7 +1042,7 @@
       },
       {
         "requires": ["pywin32 (>1.0)"],
-        "environment": "sys.platform == 'win32'"
+        "environment": "sys_platform == 'win32'"
       }
     ]
 
@@ -1369,6 +1109,11 @@
 A version declaration may be supplied and must follow the rules described
 in PEP 440.
 
+An inactive project may be explicitly indicated by setting this field to
+``None`` (which is serialised as ``null`` in JSON as usual).
+
+Automated tools SHOULD report a warning when installing an obsolete project.
+
 Possible uses for this field include handling project name changes and
 project mergers.
 
@@ -1441,321 +1186,39 @@
    "supports_environments": ["python_version >= '2.6' and sys_platform != 'win32'",
                              "python_version >= '3.3' and sys_platform == 'win32'"]
 
-Installed interfaces
-====================
-
-Most Python distributions expose packages and modules for import through
-the Python module namespace. Distributions may also expose other
-interfaces when installed.
-
-Export specifiers
------------------
-
-An export specifier is a string consisting of a fully qualified name, as
-well as an optional extra name enclosed in square brackets. This gives the
-following four possible forms for an export specifier::
-
-   module
-   module:name
-   module[requires_extra]
-   module:name[requires_extra]
-
-.. note::
-
-   The jsonschema file currently restricts qualified names using the
-   Python 2 ASCII identifier rules. This may need to be reconsidered
-   given the more relaxed identifier rules in Python 3.
-
-The meaning of the subfields is as follows:
-
-* ``module``: the module providing the export
-* ``name``: if applicable, the qualified name of the export within the module
-* ``requires_extra``: indicates the export will only work correctly if the
-  additional dependencies named in the given extra are available in the
-  installed environment
-
-.. note::
-
-   I tried this as a mapping with subfields, and it made the examples below
-   unreadable. While this PEP is mostly for tool use, readability still
-   matters to some degree for debugging purposes, and because I expect
-   snippets of the format to be reused elsewhere.
-
-
-Modules
--------
-
-A list of qualified names of modules and packages that the distribution
-provides for import.
-
-.. note::
-
-   The jsonschema file currently restricts qualified names using the
-   Python 2 ASCII identifier rules. This may need to be reconsidered
-   given the more relaxed identifier rules in Python 3.
-
-For names that contain dots, the portion of the name before the final dot
-MUST appear either in the installed module list or in the namespace package
-list.
-
-To help avoid name conflicts, it is RECOMMENDED that distributions provide
-a single top level module or package that matches the distribution name
-(or a lower case equivalent). This requires that the distribution name also
-meet the requirements of a Python identifier, which are stricter than
-those for distribution names). This practice will also make it easier to
-find authoritative sources for modules.
-
-Index servers SHOULD allow multiple distributions to publish the same
-modules, but MAY notify distribution authors of potential conflicts.
-
-Installation tools SHOULD report an error when asked to install a
-distribution that provides a module that is also provided by a different,
-previously installed, distribution.
-
-Note that attempting to import some declared modules may result in an
-exception if the appropriate extras are not installed.
-
-Example::
-
-    "modules": ["chair", "chair.cushions", "python_sketches.nobody_expects"]
-
-.. note::
-
-   Making this a list of export specifiers instead would allow a distribution
-   to declare when a particular module requires a particular extra in order
-   to run correctly. On the other hand, there's an argument to be made that
-   that is the point where it starts to become worthwhile to split out a
-   separate distribution rather than using extras.
-
-
-Namespaces
-----------
-
-A list of qualified names of namespace packages that the distribution
-contributes modules to.
-
-.. note::
-
-   The jsonschema file currently restricts qualified names using the
-   Python 2 ASCII identifier rules. This may need to be reconsidered
-   given the more relaxed identifier rules in Python 3.
-
-On versions of Python prior to Python 3.3 (which provides native namespace
-package support), installation tools SHOULD emit a suitable ``__init__.py``
-file to properly initialise the namespace rather than using a distribution
-provided file.
-
-Installation tools SHOULD emit a warning and MAY emit an error if a
-distribution declares a namespace package that conflicts with the name of
-an already installed module or vice-versa.
-
-Example::
-
-    "namespaces": ["python_sketches"]
-
-
-Commands
---------
-
-The ``commands`` mapping contains three subfields:
-
-* ``wrap_console``: console wrapper scripts to be generated by the installer
-* ``wrap_gui``: GUI wrapper scripts to be generated by the installer
-* ``prebuilt``: scripts created by the distribution's build process and
-  installed directly to the configured scripts directory
-
-``wrap_console`` and ``wrap_gui`` are both mappings of script names to
-export specifiers. The script names must follow the same naming rules as
-distribution names.
-
-The export specifiers for wrapper scripts must refer to either a package
-with a __main__ submodule (if no ``name`` subfield is given in the export
-specifier) or else to a callable inside the named module.
-
-Installation tools should generate appropriate wrappers as part of the
-installation process.
-
-.. note::
-
-   Still needs more detail on what "appropriate wrappers" means. For now,
-   refer to what setuptools and zc.buildout generate as wrapper scripts.
-
-``prebuilt`` is a list of script paths, relative to the scripts directory in
-a wheel file or following installation. They are provided for informational
-purpose only - installing them is handled through the normal processes for
-files created when building a distribution.
-
-Index servers SHOULD allow multiple distributions to publish the same
-commands, but MAY notify distribution authors of potential conflicts.
-
-Installation tools SHOULD report an error when asked to install a
-distribution that provides a command that is also provided by a different,
-previously installed, distribution.
-
-Example::
-
-    "commands": {
-      "wrap_console": [{"wrapwithpython": "chair:run_cli"}],
-      "wrap_gui": [{"wrapwithpythonw": "chair:run_gui"}],
-      "prebuilt": ["notawrapper"]
-    }
-
-
-
-Exports
--------
-
-The ``exports`` field is a mapping containing prefixed names as keys. Each
-key identifies an export group containing one or more exports published by
-the distribution.
-
-Export group names are defined by distributions that will then make use of
-the published export information in some way. The primary use case is for
-distributions that support a plugin model: defining an export group allows
-other distributions to indicate which plugins they provide, how they
-can be imported and accessed, and which additional dependencies (if any)
-are needed for the plugin to work correctly.
-
-To reduce the chance of name conflicts, export group names SHOULD use a
-prefix that corresponds to a module name in the distribution that defines
-the meaning of the export group. This practice will also make it easier to
-find authoritative documentation for export groups.
-
-Each individual export group is then a mapping of arbitrary non-empty string
-keys to export specifiers. The meaning of export names within an export
-group is up to the distribution that defines the export group. Creating an
-appropriate definition for the export name format can allow the importing
-distribution to determine whether or not an export is relevant without
-needing to import every exporting module.
-
-Example::
-
-    "exports": {
-      "nose.plugins.0.10": {
-        "chairtest": "chair:NosePlugin"
-      }
-    }
-
-
-Install hooks
-=============
-
-The ``install_hooks`` field is used to define operations to be
-invoked on the distribution  in the following situations:
-
-* Installing to a deployment system
-* Uninstalling from a deployment system
-
-Distributions may define handlers for each of these operations as an
-"entry point", which is a reference to a Python callable, with the module
-name separated from the reference within the module by a colon (``:``).
-
-Example install hooks::
-
-    "install_hooks": {
-      "postinstall": "ComfyChair.install_hooks:postinstall",
-      "preuininstall": "ComfyChair.install_hooks:preuninstall"
-    }
-
-The currently defined install hooks are:
-
-* ``postinstall``: run after the distribution has been installed to a
-  target deployment system (or after it has been upgraded). If the hook is
-  not defined, it indicates no distribution specific actions are needed
-  following installation.
-* ``preuninstall``: run before the distribution has been uninstalled from a
-  deployment system (or before it is upgraded). If the hook is not defined,
-  it indicates no distribution specific actions are needed prior to
-  uninstallation.
-
-The required signatures of these hooks are as follows::
-
-    def postinstall(current_meta, previous_meta=None):
-        """Run following installation or upgrade of the distribution
-
-        *current_meta* is the distribution metadata for the version now
-        installed on the current system
-        *previous_meta* is either omitted or ``None`` (indicating a fresh
-        install) or else the distribution metadata for the version that
-        was previously installed (indicating an upgrade or downgrade).
-        """
-
-    def preuninstall(current_meta, next_meta=None):
-        """Run prior to uninstallation or upgrade of the distribution
-
-        *current_meta* is the distribution metadata for the version now
-        installed on the current system
-        *next_meta* is either omitted or ``None`` (indicating complete
-        uninstallation) or else the distribution metadata for the version
-        that is about to be installed (indicating an upgrade or downgrade).
-        """
-
-When install hooks are defined, it is assumed that they MUST be executed
-to obtain a properly working installation of the distribution, and to
-properly remove the distribution from a system.
-
-Install hooks SHOULD NOT be used to provide functionality that is
-expected to be provided by installation tools (such as rewriting of
-shebang lines and generation of executable wrappers for Windows).
-
-Installation tools MUST ensure the distribution is fully installed, and
-available through the import system and installation database when invoking
-install hooks.
-
-Installation tools MUST call install hooks with full metadata, rather than
-only the essential dependency resolution metadata.
-
-The given parameter names are considered part of the hook signature.
-Installation tools MUST call install hooks solely with keyword arguments.
-Install hook implementations MUST use the given parameter names.
-
-Installation tools SHOULD invoke install hooks automatically after
-installing a distribution from a binary archive.
-
-When installing from an sdist, source archive or VCS checkout, installation
-tools SHOULD create a binary archive using ``setup.py bdist_wheel`` and
-then install binary archive normally (including invocation of any install
-hooks). Installation tools SHOULD NOT invoke ``setup.py install`` directly.
-
-Installation tools SHOULD treat an exception thrown by a postinstall hook
-as a failure of the installation and revert any other changes made to the
-system.
-
-Installation tools SHOULD treat an exception thrown by a preuninstall hook
-as an indication the removal of the distribution should be aborted.
-
-Installation tools MUST NOT silently ignore install hooks, as failing
-to call these hooks may result in a misconfigured installation that fails
-unexpectedly at runtime. Installation tools MAY refuse to install
-distributions that define install hooks, or require that users
-explicitly opt in to permitting the execution of such hooks.
-
-Install hook implementations MUST NOT make any assumptions regarding the
-current working directory when they are invoked, and MUST NOT make
-persistent alterations to the working directory or any other process global
-state (other than potentially importing additional modules, or other
-expected side effects of running the distribution).
-
-Install hooks have access to the full metadata for the release being
-installed, that of the previous/next release (as appropriate), as well as
-to all the normal runtime information (such as available imports). Hook
-implementations can use this information to perform additional platform
-specific installation steps. To check for the presence or absence of
-"extras", hook implementations should use the same runtime checks that
-would be used during normal operation (such as checking for the availability
-of the relevant dependencies).
-
 
 Metadata Extensions
 ===================
 
-Extensions to the metadata may be present in a mapping under the
-'extensions' key.  The keys must be valid prefixed names, while
-the values may be any type natively supported in JSON::
+Extensions to the metadata MAY be present in a mapping under the
+``extensions`` key.  The keys MUST be valid prefixed names, while
+the values MUST themselves be nested mappings.
+
+The following example shows the ``python.details`` and ``python.commands``
+standard extensions from :pep:`459`::
 
     "extensions" : {
-      "chili" : { "type" : "Poblano", "heat" : "Mild" },
-      "languages" : [ "French", "Italian", "Hebrew" ]
+      "python.details": {
+        "license": "GPL version 3, excluding DRM provisions",
+        "keywords": [
+          "comfy", "chair", "cushions", "too silly", "monty python"
+        ],
+        "classifiers": [
+          "Development Status :: 4 - Beta",
+          "Environment :: Console (Text Based)",
+          "License :: OSI Approved :: GNU General Public License v3 (GPLv3)"
+        ],
+        "document_names": {
+            "description": "README.rst",
+            "license": "LICENSE.rst",
+            "changelog": "NEWS"
+        }
+      },
+      "python.commands": {
+        "wrap_console": [{"chair": "chair:run_cli"}],
+        "wrap_gui": [{"chair-gui": "chair:run_gui"}],
+        "prebuilt": ["reduniforms"]
+      },
     }
 
 Extension names are defined by distributions that will then make use of
@@ -1766,11 +1229,22 @@
 the meaning of the extension. This practice will also make it easier to
 find authoritative documentation for metadata extensions.
 
+Extensions MUST be versioned, using the ``extension_version`` key.
+However, if this key is omitted, then the implied version is ``1.0``.
+
+Automated tools consuming extension metadata SHOULD warn if
+``extension_version`` is greater than the highest version they support,
+and MUST fail if ``extension_version`` has a greater major version than
+the highest version they support (as described in PEP 440, the major
+version is the value before the first dot).
+
+For broader compatibility, build tools MAY choose to produce
+extension metadata using the lowest metadata version that includes
+all of the needed fields.
+
 Metadata extensions allow development tools to record information in the
-metadata that may be useful during later phases of distribution. For
-example, a build tool could include default build options in a metadata
-extension when creating an sdist, and use those when creating the wheel
-files later.
+metadata that may be useful during later phases of distribution, but is
+not essential for dependency resolution or building the software.
 
 
 Extras (optional dependencies)
@@ -1989,7 +1463,12 @@
   generation Python Package Index implementation
 * the `distlib project <https://bitbucket.org/pypa/distlib/>`__ which is
   derived from the core packaging infrastructure created for the
-  ``distutils2`` project and
+  ``distutils2`` project
+
+.. note::
+
+   These tools have yet to be updated for the switch to standard extensions
+   for several fields.
 
 While it is expected that there may be some edge cases where manual
 intervention is needed for clean conversion, the specification has been
@@ -2071,9 +1550,8 @@
 
 * The "Extras" optional dependency mechanism
 
-* A well-defined metadata extension mechanism
-
-* Install hook system
+* A well-defined metadata extension mechanism, and migration of any fields
+  not needed for dependency resolution to standard extensions.
 
 * Clarify and simplify various aspects of environment markers:
 
@@ -2081,14 +1559,16 @@
   * consistently use underscores instead of periods in the variable names
   * allow ordered string comparisons and chained comparisons
 
+* New system for defining supported environments
+
+* Updated obsolescence mechanism
+
+* Metadata hook system
+
 * More flexible system for defining contact points and contributors
 
 * Defined a recommended set of project URLs
 
-* New system for defining supported environments
-
-* Updated obsolescence mechanism
-
 * Identification of supporting documents in the ``dist-info`` directory:
 
   * Allows markup formats to be indicated through file extensions
@@ -2160,8 +1640,8 @@
 versioning scheme.
 
 
-Build labels
-------------
+Source labels
+-------------
 
 See PEP 440 for the rationale behind the addition of this field.
 
@@ -2189,7 +1669,7 @@
 conflicting with the existing terminology in setuptools and previous
 versions of the metadata standard. Specifically, the names ``requires``,
 ``install_requires`` and ``setup_requires`` are not used, which will
-hopefully reduce confustion when converting legacy metadata to the new
+hopefully reduce confusion when converting legacy metadata to the new
 standard.
 
 
@@ -2227,10 +1707,13 @@
 packages, and inclusion of CVE references to mark security releases.
 
 
-Support for install hooks
+Support for metadata hooks
 ---------------------------
 
-The new install hook system is designed to allow the wheel format to fully
+This feature is provided by the ``python.metadata_hooks`` extension in
+:pep:`459`.
+
+The new metadata hook system is designed to allow the wheel format to fully
 replace direct installation on deployment targets, by allowing projects to
 explicitly define code that should be executed following installation from
 a wheel file.
@@ -2252,7 +1735,7 @@
 meaning they cannot be deferred to implicit execution on first use of the
 distribution.
 
-The install hook and metadata extension systems allow support for such
+The metadata hook and metadata extension systems allow support for such
 activities to be pursued independently by the individual platform
 communities, while still interoperating with the cross-platform Python
 tools.
@@ -2291,6 +1774,9 @@
 Updated contact information
 ---------------------------
 
+This feature is provided by the ``python.project`` and
+``python.integrator`` extensions in :pep:`459`.
+
 The switch to JSON made it possible to provide a more flexible
 system for defining multiple contact points for a project, as well as
 listing other contributors.
@@ -2303,6 +1789,9 @@
 Changes to project URLs
 -----------------------
 
+This feature is provided by the ``python.project`` and
+``python.integrator`` extensions in :pep:`459`.
+
 In addition to allow arbitrary strings as project URL labels, the new
 metadata standard also defines a recommend set of four URL labels for
 a distribution's home page, documentation, source control and issue tracker.
@@ -2340,6 +1829,8 @@
 Included text documents
 -----------------------
 
+This feature is provided by the ``python.details`` extension in :pep:`459`.
+
 Currently, PyPI attempts to determine the description's markup format by
 rendering it as reStructuredText, and if that fails, treating it as plain
 text.
@@ -2425,40 +1916,14 @@
 than a little strange.
 
 
-Module and file listings
-------------------------
-
-Derived metadata giving the modules and files included in built
-distributions may be useful at some point in the future. (At least RPM
-provides this, and I believe the APT equivalent does as well)
-
-Explicitly providing a list of public module names will likely help
-with enabling features in RPM like "Requires: python(requests)", as well
-as providing richer static metadata for analysis from PyPI.
-
-However, this is just extra info that doesn't impact reliably installing
-from wheels, so it is a good candidate for postponing to metadata 2.1
-(at the earliest).
-
-
 Additional install hooks
 ------------------------
 
-In addition to the postinstall and preuninstall hooks described in the PEP,
-other distribution systems (like RPM) include the notion of preinstall
-and postuninstall hooks. These hooks would run with the runtime dependencies
-installed, but without the distribution itself. These have been deliberately
-omitted, as they're well suited to being explored further as metadata
-extensions.
-
-Similarly, the idea of "optional" postinstall and preuninstall hooks can
-be pursued as a metadata extension.
-
-By contrast, the mandatory postinstall and preuninstall hooks have been
-included directly in the PEP, specifically to ensure installation tools
-don't silently ignore them. This ensures users will either be able to
-install such distributions, or else receive an explicit error at installation
-time.
+In addition to the postinstall and postuninstall hooks currently described
+in :pep:`459`, other distribution systems (like RPM) include the notion of
+preinstall and postuninstall hooks. These hooks would run with the runtime
+dependencies installed, but without the distribution itself. These have
+been deliberately omitted for the time being.
 
 
 Metabuild system
diff --git a/pep-0440.txt b/pep-0440.txt
--- a/pep-0440.txt
+++ b/pep-0440.txt
@@ -9,7 +9,7 @@
 Type: Standards Track
 Content-Type: text/x-rst
 Created: 18 Mar 2013
-Post-History: 30 Mar 2013, 27 May 2013, 20 Jun 2013
+Post-History: 30 Mar 2013, 27 May 2013, 20 Jun 2013, 21 Dec 2013
 Replaces: 386
 
 
@@ -91,6 +91,15 @@
 Any given release will be a "final release", "pre-release", "post-release" or
 "developmental release" as defined in the following sections.
 
+All numeric components MUST be non-negative integers.
+
+All numeric components MUST be interpreted and ordered according to their
+numeric value, not as text strings.
+
+All numeric components MAY be zero. Except as described below for the
+release segment, a numeric component of zero has no special significance
+aside from always being the lowest possible value in the version ordering.
+
 .. note::
 
    Some hard to read version identifiers are permitted by this scheme in
@@ -103,6 +112,41 @@
    sections.
 
 
+Local version identifiers
+-------------------------
+
+Local version identifiers MUST comply with the following scheme::
+
+    <public version identifier>[-N[.N]+]
+
+Local version identifiers are used to denote fully API compatible patched
+versions of upstream projects. These are created by application developers
+and system integrators when upgrading to a new upstream release would be too
+disruptive to the application or other integrated system (such as a Linux
+distribution).
+
+Local version identifiers may be used anywhere a public version identifier
+is expected.
+
+Local version identifiers MUST NOT include leading or trailing whitespace.
+
+Numeric components in the integrator suffix are interpreted in the same way
+as the numeric components of the release segment.
+
+The additional segment after the hyphen is referred to as the "integrator
+suffix", and makes it possible to differentiate upstream releases from
+potentially altered rebuilds by downstream integrators. The inclusion of an
+integrator suffix does not affect the kind of a release, but indicates that
+it may not contain the exact same code as the corresponding upstream release.
+
+Public index servers SHOULD NOT allow the use of local version identifiers
+in uploaded distributions. Local version identifiers are intended as a tool
+for software integrators rather than publishers.
+
+Distributions using a local version identifier SHOULD provide the
+``python.integrator`` extension metadata (as defined in :pep:`459`).
+
+
 Source labels
 -------------
 
@@ -146,12 +190,6 @@
 segments with different numbers of components, the shorter segment is
 padded out with additional zeroes as necessary.
 
-Date based release numbers are declared to be incompatible with this scheme,
-as their use is not consistent with the expected API versioning semantics
-described below. Accordingly, automated tools SHOULD report an error
-when encountering a leading release component greater than or equal
-to ``1980``.
-
 While any number of additional components after the first are permitted
 under this scheme, the most common variants are to use two components
 ("major.minor") or three components ("major.minor.micro").
@@ -169,6 +207,7 @@
     1.1
     2.0
     2.0.1
+    ...
 
 A release series is any set of final release numbers that start with a
 common prefix. For example, ``3.3.1``, ``3.3.5`` and ``3.3.9.45`` are all
@@ -181,6 +220,21 @@
    form to ``X.Y.0`` when comparing it to any release segment that includes
    three components.
 
+Date based release segments are also permitted, and are treated differently
+in some cases when used in version specifiers. Any version identifier where
+the leading component in the release segment is greater than or equal to
+``1980`` is considered to be a date based release.
+
+An example of a date based release scheme using the year and month of the
+release::
+
+    2012.04
+    2012.07
+    2012.10
+    2013.01
+    2013.06
+    ...
+
 
 Pre-releases
 ------------
@@ -359,6 +413,18 @@
     1.1.dev1
     ...
 
+Date based releases, using an incrementing serial within each year, skipping
+zero::
+
+    2012.1
+    2012.2
+    2012.3
+    ...
+    2012.15
+    2013.1
+    2013.2
+    ...
+
 
 Summary of permitted suffixes and relative ordering
 ---------------------------------------------------
@@ -423,6 +489,19 @@
     1.0.post456
     1.1.dev1
 
+The integrator suffix of local version identifiers that share a common
+public version identifier prefix MUST be sorted in the same order as
+Python's tuple sorting when the integrator suffix is parsed as follows
+(this is the same definition as is used for the release segment)::
+
+    tuple(map(int, integrator_suffix.split(".")))
+
+All integrator suffixes involved in the comparison MUST be converted to a
+consistent length by padding shorter segments with zeroes as needed.
+
+All local version identifiers (even the ``-0`` suffix) are sorted *after*
+the corresponding unqualified public version identifier.
+
 
 Version ordering across different metadata versions
 ---------------------------------------------------
@@ -485,7 +564,7 @@
 plus sign (builds - clause 11) are *not* compatible with this PEP
 and are not permitted in the public version field.
 
-One possible mechanism to translate such semantic versioning based build
+One possible mechanism to translate such semantic versioning based source
 labels to compatible public versions is to use the ``.devN`` suffix to
 specify the appropriate version order.
 
@@ -505,20 +584,6 @@
 used to record the original DVCS based version label.
 
 
-Date based versions
-~~~~~~~~~~~~~~~~~~~
-
-As with other incompatible version schemes, date based versions can be
-stored in the source label field. Translating them to a compliant
-public version is straightforward: use a leading ``"0."`` prefix in the
-public version label, with the date based version number as the remaining
-components in the release segment.
-
-This has the dual benefit of allowing subsequent migration to version
-numbering based on API compatibility, as well as triggering more appropriate
-version comparison semantics.
-
-
 Olson database versioning
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -526,13 +591,13 @@
 Olson timezone database versioning scheme: the year followed by a lowercase
 character indicating the version of the database within that year.
 
-This can be translated to a compliant 3-part version identifier as
-``0.<year>.<serial>``, where the serial starts at zero (for the '<year>a'
+This can be translated to a compliant public version identifier as
+``<year>.<serial>``, where the serial starts at zero (for the '<year>a'
 release) and is incremented with each subsequent database update within the
 year.
 
 As with other translated version identifiers, the corresponding Olson
-database version would be recorded in the source label field.
+database version could be recorded in the source label field.
 
 
 Version specifiers
@@ -546,7 +611,8 @@
 The comparison operator (or lack thereof) determines the kind of version
 clause:
     
-* No operator: equivalent to ``~=``
+* No operator: equivalent to ``>=`` for date based releases, and to ``~=``
+  otherwise
 * ``~=``: `Compatible release`_ clause
 * ``==``: `Version matching`_ clause
 * ``!=``: `Version exclusion`_ clause
@@ -578,6 +644,10 @@
 The specified version identifier must be in the standard format described in
 `Version scheme`_.
 
+Automated tools SHOULD report an error when this operator is used in
+conjunction with a date based version identifier, as it assumes the use
+of semantic API versioning.
+
 For a given release identifier ``V.N``, the compatible release clause is
 approximately equivalent to the pair of comparison clauses::
 
@@ -627,11 +697,16 @@
 The specified version identifier must be in the standard format described in
 `Version scheme`_, but a trailing ``.*`` is permitted as described below.
 
+If the specified version identifier is a public version identifier (no
+integrator suffix), then the integrator suffix of any candidate versions
+MUST be ignored when matching versions.
+
 By default, the version matching operator is based on a strict equality
 comparison: the specified version must be exactly the same as the requested
 version. The *only* substitution performed is the zero padding of the
 release segment to ensure the release segments are compared with the same
-length.
+length (and similarly for the integrator suffix, if matching against a
+specified local version identifier).
 
 Whether or not strict version matching is appropriate depends on the specific
 use case for the version specifier. Automated tools SHOULD at least issue
@@ -670,6 +745,10 @@
 those of the `Version matching`_ operator, except that the sense of any
 match is inverted.
 
+If the specified version identifier is a public version identifier (no
+integrator suffix), then the integrator suffix of any candidate versions
+MUST be ignored when excluding versions.
+
 For example, given the version ``1.1.post1``, the following clauses would
 match or not as shown::
     
@@ -692,6 +771,10 @@
 As with version matching, the release segment is zero padded as necessary to
 ensure the release segments are compared with the same length.
 
+Local version identifiers are handled according to the combination of their
+handling by the version matching operator and the consistent ordering
+defined by the standard version scheme.
+
 
 Exclusive ordered comparison
 ----------------------------
@@ -711,6 +794,10 @@
 the given version, even if acceptance of pre-releases is enabled as
 described in the section below.
 
+Local version identifiers are handled according to the combination of their
+handling by the version exclusion operator and the consistent ordering
+defined by the standard version scheme.
+
 
 Handling of pre-releases
 ------------------------
@@ -788,13 +875,14 @@
 
     pip (from file:///localbuilds/pip-1.3.1-py33-none-any.whl)
 
-All direct references that do not refer to a local file URL SHOULD
-specify a secure transport mechanism (such as ``https``), include an
-expected hash value in the URL for verification purposes, or both. If an
-insecure transport is specified without any hash information, with hash
-information that the tool doesn't understand, or with a selected hash
-algorithm that the tool considers too weak to trust, automated tools
-SHOULD at least emit a warning and MAY refuse to rely on the URL.
+All direct references that do not refer to a local file URL SHOULD specify
+a secure transport mechanism (such as ``https``) AND include an expected
+hash value in the URL for verification purposes. If a direct reference is
+specified without any hash information, with hash information that the
+tool doesn't understand, or with a selected hash algorithm that the tool
+considers too weak to trust, automated tools SHOULD at least emit a warning
+and MAY refuse to rely on the URL. If such a direct reference also uses an
+insecure transport, automated tools SHOULD NOT rely on the URL.
 
 It is RECOMMENDED that only hashes which are unconditionally provided by
 the latest version of the standard library's ``hashlib`` module be used
@@ -806,18 +894,33 @@
 specified by including a ``<hash-algorithm>=<expected-hash>`` entry as
 part of the URL fragment.
 
-Version control references, the ``VCS+protocol`` scheme SHOULD be
-used to identify both the version control system and the secure transport.
+For version control references, the ``VCS+protocol`` scheme SHOULD be
+used to identify both the version control system and the secure transport,
+and a version control system with hash based commit identifiers SHOULD be
+used. Automated tools MAY omit warnings about missing hashes for version
+control systems that do not provide hash based commit identifiers.
 
-To support version control systems that do not support including commit or
+To handle version control systems that do not support including commit or
 tag references directly in the URL, that information may be appended to the
-end of the URL using the ``@<tag>`` notation.
+end of the URL using the ``@<commit-hash>`` or the ``@<tag>#<commit-hash>``
+notation.
+
+.. note::
+
+   This isn't *quite* the same as the existing VCS reference notation
+   supported by pip. Firstly, the distribution name is moved in front rather
+   than embedded as part of the URL. Secondly, the commit hash is included
+   even when retrieving based on a tag, in order to meet the requirement
+   above that *every* link should include a hash to make things harder to
+   forge (creating a malicious repo with a particular tag is easy, creating
+   one with a specific *hash*, less so).
 
 Remote URL examples::
 
-    pip (from https://github.com/pypa/pip/archive/1.3.1.zip)
-    pip (from http://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686)
-    pip (from git+https://github.com/pypa/pip.git@1.3.1)
+    pip (from https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686)
+    pip (from git+https://github.com/pypa/pip.git@7921be1537eac1e97bc40179a57f0349c2aee67d)
+    pip (from git+https://github.com/pypa/pip.git@1.3.1#7921be1537eac1e97bc40179a57f0349c2aee67d)
+
 
 
 Updating the versioning specification
@@ -840,7 +943,11 @@
   on DVCS hashes
 
 * Added the "direct reference" concept as a standard notation for direct
-  references to resources (rather than each tool needing to invents its own)
+  references to resources (rather than each tool needing to invent its own)
+
+* Added the "local version identifier" and "integrator suffix" concepts to
+  allow system integrators to indicate patched builds in a way that is
+  supported by the upstream tools
 
 * Added the "compatible release" clause
 
@@ -853,7 +960,7 @@
 
 * Explicit exclusion of leading or trailing whitespace
 
-* Explicit criterion for the exclusion of date based versions
+* Explicit support for date based versions
 
 * Implicitly exclude pre-releases unless they're already present or
   needed to satisfy a dependency
@@ -1039,6 +1146,29 @@
 ordered comparison clauses.
 
 
+Support for date based version identifiers
+------------------------------------------
+
+Excluding date based versions caused significant problems in migrating
+``pytz`` to the new metadata standards. It also caused concerns for the
+OpenStack developers, as they use a date based versioning scheme and would
+like to be able to migrate to the new metadata standards without changing
+it.
+
+The approach now adopted in the PEP is to:
+
+* consider a leading release segment component greater than or equal to
+  ``1980`` to denote a "date based release"
+* using ``>=`` rather than ``~=`` as the default comparison operator for
+  version specifier clauses based on a date based release
+* recommend reporting an error if ``~=`` is used with a date based release
+
+This approach means that date based version identifiers should "just work"
+for ``pytz`` and any other projects with stable APIs, and at least be usable
+(through the use of appropriate version specifiers on the consumer side) for
+projects with less stable APIs.
+
+
 Adding direct references
 ------------------------
 
@@ -1057,6 +1187,38 @@
 as well as reducing PyPI's own apparent reliability.
 
 
+Adding local version identifiers
+--------------------------------
+
+It's a fact of life that downstream integrators often need to backport
+upstream bug fixes to older versions. It's one of the services that gets
+Linux distro vendors paid, and application developers may also apply patches
+they need to bundled dependencies.
+
+Historically, this practice has been invisible to cross-platform language
+specific distribution tools - the reported "version" in the upstream
+metadata is the same as for the unmodified code. This inaccuracy then
+can then cause problems when attempting to work with a mixture of integrator
+provided code and unmodified upstream code, or even just attempting to
+identify exactly which version of the software is installed.
+
+The introduction of local version identifiers and the "integrator suffix"
+into the versioning scheme, with the corresponding ``python.integrator``
+metadata extension allows this kind of activity to be represented
+accurately, which should improve interoperability between the upstream
+tools and various integrated platforms.
+
+The exact scheme chosen is largely modelled on the existing behaviour of
+``pkg_resources.parse_version`` and ``pkg_resources.parse_requirements``,
+with the main distinction being that where ``pkg_resources`` currently always
+takes the suffix into account when comparing versions for exact matches,
+the PEP requires that the integrator suffix of the candidate version be
+ignored when no integrator suffix is present in the version specifier clause.
+
+This change is designed to ensure that an integrator provided version like
+``pip 1.5-1`` will still satisfy a version specifier like ``pip (== 1.1)``.
+
+
 References
 ==========
 
diff --git a/pep-0459.txt b/pep-0459.txt
--- a/pep-0459.txt
+++ b/pep-0459.txt
@@ -10,7 +10,7 @@
 Content-Type: text/x-rst
 Requires: 426
 Created: 11 Nov 2013
-Post-History:
+Post-History: 21 Dec 2013
 
 
 Abstract
@@ -49,6 +49,10 @@
 * ``python.exports``
 * ``python.metadata_hooks``
 
+All standard extensions are currently at version ``1.0``, and thus the
+``extension_metadata`` field may be omitted without losing access to any
+functionality.
+
 
 The ``details`` extension
 =========================
@@ -502,9 +506,9 @@
 Example::
 
     "commands": {
-      "wrap_console": [{"wrapwithpython": "chair:run_cli"}],
-      "wrap_gui": [{"wrapwithpythonw": "chair:run_gui"}],
-      "prebuilt": ["notawrapper"]
+      "wrap_console": [{"chair": "chair:run_cli"}],
+      "wrap_gui": [{"chair-gui": "chair:run_gui"}],
+      "prebuilt": ["reduniforms"]
     }
 
 
@@ -532,18 +536,18 @@
 
 The currently defined metadata hooks are:
 
-* ``install``: run after a relevant distribution has been installed,
+* ``postinstall``: run after a relevant distribution has been installed,
   upgraded or downgraded on the current system. May also be run as part
   of a system state resync operation. If the hook is not defined, it
   indicates no distribution specific actions are needed following
   installation.
-* ``uninstall``: run after a relevant distribution has been completely
+* ``postuninstall``: run after a relevant distribution has been completely
   removed from the current system. If the hook is not defined, it indicates
   no distribution specific actions are needed following uninstallation.
 
 The required signatures of these hooks are as follows::
 
-    def install(current_meta, previous_meta=None):
+    def postinstall(current_meta, previous_meta=None):
         """Run following installation or upgrade of a relevant distribution
 
         *current_meta* is the distribution metadata for the version now
@@ -554,7 +558,7 @@
         resynchronisation of the system state).
         """
 
-    def uninstall(previous_meta):
+    def postuninstall(previous_meta):
         """Run after complete uninstallation of a relevant distribution
 
         *previous_meta* is the distribution metadata for the version that
@@ -568,8 +572,8 @@
 
     "export_groups": {
       "ComfyChair.plugins": {
-        "install": "ComfyChair.plugins:install_hook",
-        "uininstall": "ComfyChair.plugins:uninstall_hook"
+        "postinstall": "ComfyChair.plugins:install_hook",
+        "postuininstall": "ComfyChair.plugins:uninstall_hook"
       }
     }
 
@@ -588,16 +592,16 @@
 
     "extensions": {
       "python.exports": {
-        "install": "pip.export_group_hooks:run_install_hooks",
-        "uininstall": "pip.export_group_hooks:run_uninstall_hooks"
+        "postinstall": "pip.export_group_hooks:run_install_hooks",
+        "postuininstall": "pip.export_group_hooks:run_uninstall_hooks"
       }
       "python.commands": {
-        "install": "pip.command_hook:install_wrapper_scripts",
+        "postinstall": "pip.command_hook:install_wrapper_scripts",
       }
     }
 
 (Note: this is just an example, but the intent is that pip *could* implement
-that functionality that way if it wanted to.
+that functionality that way if it wanted to).
 
 A trailing ".*" may be used to request prefix matching rather than
 requiring an exact match on the extension name.
@@ -610,7 +614,8 @@
 
    Metadata hooks are likely to run with elevated privileges, this needs
    to be considered carefully (e.g. by *requiring* that metadata hook
-   installation be opt in).
+   installation be opt in when using the standard tools and running with
+   elevated privileges).
 
 The given parameter names are considered part of the hook signature.
 Installation tools MUST call metadata hooks solely with keyword arguments.

-- 
Repository URL: http://hg.python.org/peps


More information about the Python-checkins mailing list