[Python-checkins] peps: Explain the version scheme in PEP 426

nick.coghlan python-checkins at python.org
Sat Feb 9 13:42:26 CET 2013


http://hg.python.org/peps/rev/415f9d9a0014
changeset:   4722:415f9d9a0014
user:        Nick Coghlan <ncoghlan at gmail.com>
date:        Sat Feb 09 22:40:18 2013 +1000
summary:
  Explain the version scheme in PEP 426

files:
  pep-0426.txt |  517 +++++++++++++++++++++++++++++++-------
  1 files changed, 414 insertions(+), 103 deletions(-)


diff --git a/pep-0426.txt b/pep-0426.txt
--- a/pep-0426.txt
+++ b/pep-0426.txt
@@ -29,7 +29,7 @@
 extension mechanism.  It also adds support for optional features of
 distributions and allows the description to be placed into a payload
 section. Finally, this version addresses several issues with the
-previous iteration of the standard version numbering scheme.
+previous iteration of the standard version identification scheme.
 
 
 Metadata files
@@ -101,7 +101,7 @@
 Version
 -------
 
-A string containing the distribution's version number. See `Version scheme`_
+A string containing the distribution's version identifier. See `Version scheme`_
 below.
 
 Example::
@@ -300,7 +300,7 @@
 projects to depend only on having at least one of them installed.
 
 A version declaration may be supplied and must follow the rules described
-in `Version scheme`_. The distribution's version number will be implied
+in `Version scheme`_. The distribution's version identifier will be implied
 if none is specified.
 
 Examples::
@@ -446,7 +446,7 @@
 dependency, optionally followed by a version declaration within
 parentheses.
 
-Because they refer to non-Python software releases, version numbers
+Because they refer to non-Python software releases, version identifiers
 for this field are **not** required to conform to the format
 described in `Version scheme`_:  they should correspond to the
 version scheme used by the external dependency.
@@ -549,31 +549,310 @@
 Version scheme
 ==============
 
-Version numbers must comply with the following scheme::
+Version identifiers must comply with the following scheme::
 
-    N.N[.N]+[{a|b|c|rc}N][.postN][.devN]
+    N[.N]+[{a|b|c|rc}N][.postN][.devN]
 
-Version numbers which do not comply with this scheme are an
-error. Projects which wish to use non-compliant version numbers may
-be heuristically normalized to this scheme and are less likely to sort
-correctly.
+Version identifiers which do not comply with this scheme are an error.
+Projects which wish to use non-compliant version identifiers must restrict
+themselves to metadata v1.1 (PEP 314) or earlier, as those specifications
+do not constrain the versioning scheme.
 
-Suffixes and ordering
----------------------
+Any given version will be a "release", "pre-release", "post-release" or
+"developmental release" as defined in the following sections.
 
-The following suffixes are the only ones allowed at the given level of the
-version hierarchy and they are ordered as listed.
+.. note::
 
-Within a numeric release (``1.0``, ``2.7.3``)::
+   Some hard to read version identifiers are permitted by this scheme
+   in order to better accommodate the wide range of versioning practices
+   across existing public and private Python projects.
+
+   Accordingly, some of the versioning practices which are technically
+   permitted by the PEP are strongly discouraged for new projects. Where
+   this is the case, the relevant details are noted in the following
+   sections.
+
+
+Releases
+--------
+
+A release number is a version identifier that consists solely of one or
+more non-negative integer values, separated by dots::
+
+    N[.N]+
+
+Releases within a project must be numbered in a consistently increasing
+fashion. Ordering considers the numeric value of each component
+in turn, with "component does not exist" sorted ahead of all numeric
+values.
+
+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").
+
+For example::
+
+    0.9
+    0.9.1
+    0.9.2
+    ...
+    0.9.10
+    0.9.11
+    1.0
+    1.0.1
+    1.1
+    2.0
+    2.0.1
+
+A release series is any set of release numbers that start with a common
+prefix. For example, ``3.3.1``, ``3.3.5`` and ``3.3.9.45`` are all
+part of the ``3.3`` release series.
+
+.. note::
+
+   Using both ``X.Y`` and ``X.Y.0`` as distinct release numbers within the
+   scope of a single release series is strongly discouraged, as it makes the
+   version ordering ambiguous for human readers. Automated tools should
+   either treat this case as an error, or else interpret an ``X.Y.0``
+   release as coming *after* the corresponding ``X.Y`` release.
+
+   The recommended practice is to always use release numbers of a consistent
+   length (that is, always include the trailing ``.0``). An acceptable
+   alternative is to consistently omit the trailing ``.0``. The example
+   above shows both styles, always including the ``.0`` at the second
+   level and consistently omitting it at the third level.
+
+.. note::
+
+   While date based release numbers, using the forms ``year.month`` or
+   ``year.month.day``, are technically compliant with this scheme, their use
+   is strongly discouraged as they can hinder automatic translation to
+   other versioning schemes. In particular, they are completely
+   incompatible with semantic versioning.
+
+
+Semantic versioning
+-------------------
+
+`Semantic versioning`_ is a popular version identification scheme that is
+more prescriptive than this PEP regarding the significance of different
+elements of a release number. Even if a project chooses not to abide by
+the details of semantic versioning, the scheme is worth understanding as
+it covers many of the issues that can arise when depending on other
+distributions, and when publishing a distribution that others rely on.
+
+The "Major.Minor.Patch" (described in this PEP as "major.minor.micro")
+aspects of semantic versioning (clauses 1-9 in the 2.0.0-rc-1 specification)
+are fully compatible with the version scheme defined in this PEP, and abiding
+by these aspects is encouraged.
+
+Semantic versions containing a hyphen (pre-releases - clause 10) or a
+plus sign (builds - clause 11) are *not* compatible with this PEP
+and are not permitted in compliant metadata. Use this PEP's deliberately
+more restricted pre-release and developmental release notation instead.
+
+.. _Semantic versioning: http://semver.org/
+
+
+Pre-releases
+------------
+
+Some projects use an "alpha, beta, release candidate" pre-release cycle to
+support testing by their users prior to a full release.
+
+If used as part of a project's development cycle, these pre-releases are
+indicated by a suffix appended directly to the last component of the
+release number::
+
+    X.YaN  # Alpha release
+    X.YbN  # Beta release
+    X.YcN  # Release candidate (alternative notation: X.YrcN)
+    X.Y    # Full release
+
+The pre-release suffix consists of an alphabetical identifier for the
+pre-release phase, along with a non-negative integer value. Pre-releases for
+a given release are ordered first by phase (alpha, beta, release candidate)
+and then by the numerical component within that phase.
+
+.. note::
+
+   Using both ``c`` and ``rc`` to identify release candidates within
+   the scope of a single release is strongly discouraged, as it makes the
+   version ordering ambiguous for human readers. Automated tools should
+   either treat this case as an error, or else interpret all ``rc`` versions
+   as coming after all ``c`` versions (that is, ``rc1`` indicates a later
+   version than ``c2``).
+
+
+Post-releases
+-------------
+
+Some projects use post-releases to address minor errors in a release that
+do not affect the distributed software (for example, correcting an error
+in the release notes).
+
+If used as part of a project's development cycle, these post-releases are
+indicated by a suffix appended directly to the last component of the
+release number::
+
+    X.Y.postN    # Post-release
+
+The post-release suffix consists of the string ``.post``, followed by a
+non-negative integer value. Post-releases are ordered by their
+numerical component, immediately following the corresponding release,
+and ahead of any subsequent release.
+
+.. note::
+
+   The use of post-releases to publish maintenance releases containing
+   actual bug fixes is strongly discouraged. In general, it is better
+   to use a longer release number and increment the final component
+   for each maintenance release.
+
+Post-releases are also permitted for pre-releases::
+
+    X.YaN.postM  # Post-release of an alpha release
+    X.YbN.postM  # Post-release of a beta release
+    X.YcN.postM  # Post-release of a release candidate
+
+.. note::
+
+   Creating post-releases of pre-releases is strongly discouraged, as
+   it makes the version identifier difficult to parse for human readers.
+   In general, it is substantially clearer to simply create a new
+   pre-release by incrementing the numeric component.
+
+
+Developmental releases
+----------------------
+
+Some projects make regular developmental releases, and system packagers
+(especially for Linux distributions) may wish to create early releases
+which do not conflict with later project releases.
+
+If used as part of a project's development cycle, these developmental
+releases are indicated by a suffix appended directly to the last
+component of the release number::
+
+    X.Y.devN    # Developmental release
+
+The developmental release suffix consists of the string ``.dev``,
+followed by a non-negative integer value. Developmental releases are ordered
+by their numerical component, immediately before the corresponding release
+(and before any pre-releases), and following any previous release.
+
+Developmental releases are also permitted for pre-releases and
+post-releases::
+
+    X.YaN.devM      # Developmental release of an alpha release
+    X.YbN.devM      # Developmental release of a beta release
+    X.YcN.devM      # Developmental release of a release candidate
+    X.Y.postN.devM  # Developmental release of a post-release
+
+.. note::
+
+   Creating developmental releases of pre-releases is strongly
+   discouraged, as it makes the version identifier difficult to parse for
+   human readers. In general, it is substantially clearer to simply create
+   a additional pre-releases by incrementing the numeric component.
+
+   Developmental releases of post-releases are also generally discouraged,
+   but they may be appropriate for projects which use the post-release
+   notation for full maintenance releases which may include code changes.
+
+
+Examples of compliant version schemes
+-------------------------------------
+
+The standard version scheme is designed to encompass a wide range of
+identification practices across public and private Python projects. In
+practice, a single project attempting to use the full flexibility offered
+by the scheme would create a situation where human users had difficulty
+figuring out the relative order of versions, even though the rules above
+ensure all compliant tools will order them consistently.
+
+The following examples illustrate a small selection of the different
+approaches projects may choose to identify their releases, while still
+ensuring that the "latest release" and the "latest stable release" can
+be easily determined, both by human users and automated tools.
+
+Simple "major.minor" versioning::
+
+    0.1
+    0.2
+    0.3
+    1.0
+    1.1
+    ...
+
+Simple "major.minor.micro" versioning::
+
+    1.1.0
+    1.1.1
+    1.1.2
+    1.2.0
+    ...
+
+"major.minor" versioning with alpha, beta and release candidate
+pre-releases::
+
+    0.9
+    1.0a1
+    1.0a2
+    1.0b1
+    1.0c1
+    1.0
+    1.1a1
+    ...
+
+"major.minor" versioning with developmental releases, release candidates
+and post-releases for minor corrections::
+
+    0.9
+    1.0.dev1
+    1.0.dev2
+    1.0.dev3
+    1.0.dev4
+    1.0rc1
+    1.0rc2
+    1.0
+    1.0.post1
+    1.1.dev1
+    ...
+
+
+Summary of permitted suffixes and relative ordering
+---------------------------------------------------
+
+.. note::
+
+   This section is intended primarily for authors of tools that
+   automatically process distribution metadata, rather than authors
+   of Python distributions deciding on a versioning scheme.
+
+The numeric release component of version identifiers should be sorted in
+the same order as Python's tuple sorting when the release number is
+parsed as follows::
+
+    tuple(map(int, release_number.split(".")))
+
+Within a numeric release (``1.0``, ``2.7.3``), the following suffixes
+are permitted and are ordered as shown::
 
    .devN, aN, bN, cN, rcN, <no suffix>, .postN
 
+Note that `rc` will always sort after `c` (regardless of the numeric
+component) although they are semantically equivalent. Tools are free to
+reject this case as ambiguous and remain in compliance with the PEP.
+
 Within an alpha (``1.0a1``), beta (``1.0b1``), or release candidate
-(``1.0c1``, ``1.0rc1``)::
+(``1.0c1``, ``1.0rc1``), the following suffixes are permitted and are
+ordered as shown::
 
    .devN, <no suffix>, .postN
 
-Within a post release (``1.0.post1``)::
+Within a post-release (``1.0.post1``), the following suffixes are permitted
+and are ordered as shown::
 
     devN, <no suffix>
 
@@ -583,16 +862,7 @@
 
 Within a given suffix, ordering is by the value of the numeric component.
 
-Note that `rc` will always sort after `c` (regardless of the numeric
-component) although they are semantically equivalent. It is suggested
-that within a particular project you do not mix `c` and `rc`, especially
-within the same numeric version.
-
-
-Example version order
----------------------
-
-::
+The following example covers many of the possible combinations::
 
     1.0.dev456
     1.0a1
@@ -601,6 +871,7 @@
     1.0a12
     1.0b1.dev456
     1.0b2
+    1.0b2.post345.dev456
     1.0b2.post345
     1.0c1.dev456
     1.0c1
@@ -609,81 +880,85 @@
     1.0.post456
     1.1.dev1
 
-Recommended subset
-------------------
 
-The PEP authors recommend using a subset of the allowed version scheme,
-similar to http://semver.org/ but without hyphenated versions.
-
-* Version numbers are always three positive digits ``X.Y.Z`` (Major.Minor.Patch)
-* The patch version is incremented for backwards-compatible bug fixes.
-* The minor version is incremented for backwards-compatible API additions.
-  When the minor version is incremented the patch version resets to 0.
-* The major version is incremented for backwards-incompatible API changes.
-  When the major version is incremented the minor and patch versions
-  reset to 0.
-* Pre-release versions ending in ``a``, ``b``, and ``c`` may be used.
-* Dev- and post-release versions are discouraged.  Increment the patch number
-  instead of issuing a post-release.
-
-When the major version is 0, the API is not considered stable, may change at
-any time, and the rules about when to increment the minor and patch version
-numbers are relaxed.
-
-Ordering across different metadata versions
--------------------------------------------
+Version ordering across different metadata versions
+---------------------------------------------------
 
 Metadata v1.0 (PEP 241) and metadata v1.1 (PEP 314) do not
-specify a standard version numbering or sorting scheme. This PEP does
+specify a standard version identification or ordering scheme. This PEP does
 not mandate any particular approach to handling such versions, but
-acknowledges that the de facto standard for sorting such versions is
+acknowledges that the de facto standard for ordering them is
 the scheme used by the ``pkg_resources`` component of ``setuptools``.
 
-For metadata v1.2 (PEP 345), the recommended sort order is defined in
-PEP 386.
+Software that automatically processes distribution metadata may either
+treat non-compliant version identifiers as an error, or attempt to normalize
+them to the standard scheme. This means that projects using non-compliant
+version identifiers may not be handled consistently across different tools,
+even when correctly publishing the earlier metadata versions.
 
-The best way for a publisher to get predictable ordering is to excuse
-non-compliant versions from sorting by hiding them on PyPI or by removing
-them from any private index that is being used.  Otherwise a client
-may be restricted to using exact versions to get the correct or latest
-version of your project.
+Package developers can help ensure consistent automated handling by
+marking non-compliant versions as "hidden" on the Python Package Index
+(removing them is generally undesirable, as users may be depending on
+those specific versions being available).
+
+Package users may also wish to remove non-compliant versions from any
+private package indexes they control.
+
+For metadata v1.2 (PEP 345), the version ordering described in this PEP
+should be used in preference to the one defined in PEP 386.
+
 
 Version specifiers
 ==================
 
 A version specifier consists of a series of version clauses, separated by
 commas. Each version clause consists of an optional comparison operator
-followed by a version number. For example::
+followed by a version identifier. For example::
 
    0.9, >= 1.0, != 1.3.4, < 2.0
 
-Each version number must be in the standard format described in
+Each version identifier must be in the standard format described in
 `Version scheme`_.
 
-Comparison operators must be one of ``<``, ``>``, ``<=``, ``>=``, ``==``
-``!=``, and ``~>``.
-
-When no comparison operator is provided, it is equivalent to using ``==``.
-
-The ``~>`` operator, "equal or greater in the last digit" is equivalent
-to a pair of version clauses::
-
-    ~> 2.3.3
-
-is equivalent to::
-
-    >= 2.3.3, < 2.4.0
-
 The comma (",") is equivalent to a logical **and** operator.
 
-Whitespace between a conditional operator and the following version number
-is optional, as is the whitespace around the commas.
+Comparison operators must be one of ``<``, ``>``, ``<=``, ``>=``, ``==``
+or ``!=``.
 
-Pre-releases of any kind (indicated by the presence of ``dev``, ``a``,
-``b``, ``c`` or ``rc`` in the version number) are implicitly excluded
-from all version specifiers, *unless* a pre-release version is explicitly
-mentioned in one of the clauses. For example, this specifier implicitly
-excludes all pre-releases of later versions::
+The ``==`` and ``!=`` operators are strict - in order to match, the
+version supplied must exactly match the specified version, with no
+additional trailing suffix.
+
+However, when no comparison operator is provided along with a version
+identifier ``V``, it is equivalent to using the following pair of version
+clauses::
+
+    >= V, < V+1
+
+where ``V+1`` is the next version after ``V``, as determined by
+incrementing the last numeric component in ``V`` (for example, if
+``V == 1.0a3``, then ``V+1 == 1.0a4``, while if ``V == 1.0``, then
+``V+1 == 1.1``).
+
+This approach makes it easy to depend on a particular release series
+simply by naming it in a version specifier, without requiring any
+additional annotation. For example, the following pairs of version
+specifiers are equivalent::
+
+    2
+    >= 2, < 3
+
+    3.3
+    >= 3.3, < 3.4
+
+Whitespace between a conditional operator and the following version
+identifier is optional, as is the whitespace around the commas.
+
+Pre-releases of any kind, including developmental releases, are implicitly
+excluded from all version specifiers, *unless* a pre-release or developmental
+developmental release is explicitly mentioned in one of the clauses. For
+example, this specifier implicitly excludes all pre-releases and development
+releases of later versions::
 
     >= 1.0
 
@@ -694,13 +969,13 @@
     >= 1.0, != 1.0b2
     >= 1.0, < 2.0.dev123
 
-Dependency resolution tools should use the above rules by default, but may
-also allow users to request the following alternative behaviours:
+Dependency resolution tools should use the above rules by default, but
+should also allow users to request the following alternative behaviours:
 
 * accept already installed pre-releases for all version specifiers
 * retrieve and install available pre-releases for all version specifiers
 
-Post releases and purely numeric releases receive no special treatment -
+Post-releases and purely numeric releases receive no special treatment -
 they are always included unless explicitly excluded.
 
 Given the above rules, projects which include the ``.0`` suffix for the
@@ -711,29 +986,29 @@
 ``2.5.0``, will need to use an explicit clause like ``>= 2.5, < 2.5.1`` to
 refer specifically to that initial release.
 
-Some Examples:
+Some examples:
 
-- ``Requires-Dist: zope.interface (3.1)``: any version that starts with 3.1,
+* ``Requires-Dist: zope.interface (3.1)``: any version that starts with 3.1,
   excluding pre-releases.
-- ``Requires-Dist: zope.interface (==3.1)``: equivalent to ``Requires-Dist:
+* ``Requires-Dist: zope.interface (==3.1)``: equivalent to ``Requires-Dist:
   zope.interface (3.1)``.
-- ``Requires-Dist: zope.interface (3.1.0)``: any version that starts with
+* ``Requires-Dist: zope.interface (3.1.0)``: any version that starts with
   3.1.0, excluding pre-releases. Since that particular project doesn't
   use more than 3 digits, it also means "only the 3.1.0 release".
-- ``Requires-Python: 3``: Any Python 3 version, excluding pre-releases.
-- ``Requires-Python: >=2.6,<3``: Any version of Python 2.6 or 2.7, including
-  post releases (if they were used for Python). It excludes pre releases of
+* ``Requires-Python: 3``: Any Python 3 version, excluding pre-releases.
+* ``Requires-Python: >=2.6,<3``: Any version of Python 2.6 or 2.7, including
+  post-releases (if they were used for Python). It excludes pre releases of
   Python 3.
-- ``Requires-Python: 2.6.2``: Equivalent to ">=2.6.2,<2.6.3". So this includes
+* ``Requires-Python: 2.6.2``: Equivalent to ">=2.6.2,<2.6.3". So this includes
   only Python 2.6.2. Of course, if Python was numbered with 4 digits, it would
   include all versions of the 2.6.2 series, excluding pre-releases.
-- ``Requires-Python: 2.5``: Equivalent to ">=2.5,<2.6".
-- ``Requires-Dist: zope.interface (3.1,!=3.1.3)``: any version that starts with
-  3.1, excluding pre-releases of 3.1 *and* excluding any version that
+* ``Requires-Python: 2.5``: Equivalent to ">=2.5,<2.6".
+* ``Requires-Dist: zope.interface (3.1,!=3.1.3)``: any version that starts
+  with 3.1, excluding pre-releases of 3.1 *and* excluding any version that
   starts with "3.1.3". For this particular project, this means: "any version
   of the 3.1 series but not 3.1.3". This is equivalent to:
   ">=3.1,!=3.1.3,<3.2".
-- ``Requires-Python: >=3.3a1``: Any version of Python 3.3+, including
+* ``Requires-Python: >=3.3a1``: Any version of Python 3.3+, including
   pre-releases like 3.4a1.
 
 
@@ -910,13 +1185,14 @@
 
 The rationale for major changes is given in the following sections.
 
+
 Standard encoding and other format clarifications
 -------------------------------------------------
 
 Several aspects of the file format, including the expected file encoding,
 were underspecified in previous versions of the metadata standard. To
-simplify the process of developing interoperable tools, these details are
-now explicitly specified.
+make it easier to develop interoperable tools, these details are now
+explicitly specified.
 
 
 Changing the version scheme
@@ -939,21 +1215,56 @@
 Making this change should make it easier for affected existing projects to
 migrate to the latest version of the metadata standard.
 
-Furthermore, as the version scheme in use is dependent on the metadata
+Another change to the version scheme is to allow single number
+versions, similar to those used by non-Python projects like Mozilla
+Firefox, Google Chrome and the Fedora Linux distribution. This is actually
+expected to be more useful for version specifiers (allowing things like
+the simple ``Requires-Python: 3`` rather than the more convoluted
+``Requires-Python: >= 3.0, < 4``), but it is easier to allow it for both
+version specifiers and release numbers, rather than splitting the
+two definitions.
+
+Finally, as the version scheme in use is dependent on the metadata
 version, it was deemed simpler to merge the scheme definition directly into
 this PEP rather than continuing to maintain it as a separate PEP. This will
 also allow all of the distutils-specific elements of PEP 386 to finally be
 formally rejected.
 
 
+A more opinionated description of the versioning scheme
+-----------------------------------------------------
+
+As in PEP 386, the primary focus is on codifying existing practices to make
+them more amenable to automation, rather than demanding that existing
+projects make non-trivial changes to their workflow. However, the
+standard scheme allows significantly more flexibility than is needed
+for the vast majority of simple Python packages (which often don't even
+need maintenance releases - many users are happy with needing to upgrade to a
+new feature release to get bug fixes).
+
+For the benefit of novice developers, and for experienced developers
+wishing to better understand the various use cases, the specification
+now goes into much greater detail on the components of the defined
+version scheme, including examples of how each component may be used
+in practice.
+
+The PEP also explicitly guides developers in the direction of
+semantic versioning (without requiring it), and discourages the use of
+several aspects of the full versioning scheme that have largely been
+included in order to cover esoteric corner cases in the practices of
+existing projects and in repackaging software for Linux distributions.
+
+
 Changing the interpretation of version specifiers
 -------------------------------------------------
 
 The previous interpretation of version specifiers made it very easy to
 accidentally download a pre-release version of a dependency. This in
 turn made it difficult for developers to publish pre-release versions
-of software to the Python Package Index, as such an action would lead
-to users inadvertently downloaded pre-release software.
+of software to the Python Package Index, as leaving the package set as
+public would lead to users inadvertently downloading pre-release software,
+while hiding it would defeat the purpose of publishing it for user
+testing.
 
 The previous interpretation also excluded post-releases from some version
 specifiers for no adequately justified reason.
@@ -963,8 +1274,8 @@
 pre-release versions to be explicitly requested when needed.
 
 
-Packaging, build and installation dependencies
-----------------------------------------------
+Packaging and build and installation dependencies
+-------------------------------------------------
 
 The new ``Setup-Requires-Dist`` field allows a distribution to indicate when
 a dependency is needed to package, build or install the distribution, rather

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


More information about the Python-checkins mailing list