|
| 1 | +.. _versioning: |
| 2 | +.. _`Choosing a versioning scheme`: |
| 3 | + |
| 4 | +========== |
| 5 | +Versioning |
| 6 | +========== |
| 7 | + |
| 8 | +This discussion covers all aspects of versioning Python packages. |
| 9 | + |
| 10 | + |
| 11 | +Valid version numbers |
| 12 | +===================== |
| 13 | + |
| 14 | +Different Python projects may use different versioning schemes based on the |
| 15 | +needs of that particular project, but in order to be compatible with tools like |
| 16 | +:ref:`pip`, all of them are required to comply with a flexible format for |
| 17 | +version identifiers, for which the authoritative reference is the |
| 18 | +:ref:`specification of version specifiers <version-specifiers>`. Here are some |
| 19 | +examples of version numbers: |
| 20 | + |
| 21 | +.. code-block:: text |
| 22 | +
|
| 23 | + 1.2.0.dev1 # Development release |
| 24 | + 1.2.0a1 # Alpha Release |
| 25 | + 1.2.0b1 # Beta Release |
| 26 | + 1.2.0rc1 # Release Candidate |
| 27 | + 1.2.0 # Final Release |
| 28 | + 1.2.0.post1 # Post Release |
| 29 | + 15.10 # Date based release |
| 30 | + 23 # Serial release |
| 31 | +
|
| 32 | +
|
| 33 | +Semantic versioning vs. calendar versioning |
| 34 | +=========================================== |
| 35 | + |
| 36 | +A versioning scheme is a way to interpret version numbers of a package, and to |
| 37 | +decide which should be the next version number for a new release of a package. |
| 38 | +Two versioning schemes are commonly used for Python packages, semantic |
| 39 | +versioning and calendar versioning. |
| 40 | + |
| 41 | +Semantic versioning is recommended for most new projects. |
| 42 | + |
| 43 | +Semantic versioning |
| 44 | +------------------- |
| 45 | + |
| 46 | +The idea of *semantic versioning* is to use 3-part version numbers, |
| 47 | +*major.minor.maintenance*, where the project author increments: |
| 48 | + |
| 49 | +- *major* when they make incompatible API changes, |
| 50 | +- *minor* when they add functionality in a backwards-compatible manner, and |
| 51 | +- *maintenance*, when they make backwards-compatible bug fixes. |
| 52 | + |
| 53 | +Note that many projects, especially larger ones, do not use strict semantic |
| 54 | +versioning since many changes are technically breaking changes but affect only a |
| 55 | +small fraction of users. Such projects tend to increment the major number when |
| 56 | +the incompatibility is high, rather than for any tiny incompatibility, or to |
| 57 | +signal a shift in the project. |
| 58 | + |
| 59 | +For those projects that do adhere to semantic versioning strictly, this approach |
| 60 | +allows users to make use of :ref:`compatible release version specifiers |
| 61 | +<version-specifiers-compatible-release>`, with the ``~=`` operator. For |
| 62 | +example, ``name ~= X.Y`` is roughly equivalent to ``name >= X.Y, == X.*``, i.e., |
| 63 | +it requires at least release X.Y, and allows any later release with greater Y as |
| 64 | +long as X is the same. Likewise, ``name ~= X.Y.Z`` is roughly equivalent to |
| 65 | +``name >= X.Y.Z, == X.Y.*``, i.e., it requires at least X.Y.Z and allows a later |
| 66 | +release with same X and Y but higher Z. |
| 67 | + |
| 68 | +Python projects adopting semantic versioning should abide by clauses 1-8 of the |
| 69 | +`Semantic Versioning 2.0.0 specification <semver_>`_. |
| 70 | + |
| 71 | + |
| 72 | +Calendar versioning |
| 73 | +------------------- |
| 74 | + |
| 75 | +Semantic versioning is not a suitable choice for all projects, such as those |
| 76 | +with a regular time based release cadence and a deprecation process that |
| 77 | +provides warnings for a number of releases prior to removal of a feature. |
| 78 | + |
| 79 | +A key advantage of date-based versioning, or `calendar versioning <calver_>`_, |
| 80 | +is that it is straightforward to tell how old the base feature set of a |
| 81 | +particular release is given just the version number. |
| 82 | + |
| 83 | +Calendar version numbers typically take the form *year.month* (for example, |
| 84 | +23.10 for December 2023). |
| 85 | + |
| 86 | + |
| 87 | +Other schemes |
| 88 | +------------- |
| 89 | + |
| 90 | +Serial versioning refers to the simplest possible versioning scheme, which |
| 91 | +consists of a single number incremented every release. While serial versioning |
| 92 | +is very easy to manage as a developer, it is the hardest to track as an end |
| 93 | +user, as serial version numbers convey little or no information regarding API |
| 94 | +backwards compatibility. |
| 95 | + |
| 96 | +Combinations of the above schemes are possible. For example, a project may |
| 97 | +combine date based versioning with serial versioning to create a *year.serial* |
| 98 | +numbering scheme that readily conveys the approximate age of a release, but |
| 99 | +doesn't otherwise commit to a particular release cadence within the year. |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | +Pre-release versioning |
| 104 | +====================== |
| 105 | + |
| 106 | +Regardless of the base versioning scheme, pre-releases for a given final release |
| 107 | +may be published as: |
| 108 | + |
| 109 | +* Zero or more dev releases, denoted with a ".devN" suffix, |
| 110 | +* Zero or more alpha releases, denoted with a ".aN" suffix, |
| 111 | +* Zero or more beta releases, denoted with a ".bN" suffix, |
| 112 | +* Zero or more release candidates, denoted with a ".rcN" suffix. |
| 113 | + |
| 114 | +Pip and other modern Python package installers ignore pre-releases by default |
| 115 | +when deciding which versions of dependencies to install. |
| 116 | + |
| 117 | + |
| 118 | +Local version identifiers |
| 119 | +========================= |
| 120 | + |
| 121 | +Public version identifiers are designed to support distribution via :term:`PyPI |
| 122 | +<Python Package Index (PyPI)>`. Python packaging tools also support the notion |
| 123 | +of a :ref:`local version identifier <local-version-identifiers>`, which can be |
| 124 | +used to identify local development builds not intended for publication, or |
| 125 | +modified variants of a release maintained by a redistributor. |
| 126 | + |
| 127 | +A local version identifier takes the form of a public version identifier, |
| 128 | +followed by "+" and a local version label. For example: |
| 129 | + |
| 130 | +.. code-block:: text |
| 131 | +
|
| 132 | + 1.2.0.dev1+hg.5.b11e5e6f0b0b # 5th VCS commit since 1.2.0.dev1 release |
| 133 | + 1.2.1+fedora.4 # Package with downstream Fedora patches applied |
| 134 | +
|
| 135 | +
|
| 136 | +
|
| 137 | +
|
| 138 | +.. _calver: https://calver.org |
| 139 | +.. _semver: https://semver.org |
0 commit comments