'Rational' becomes 'Normalized'
This commit is contained in:
parent
60035e5912
commit
af0f8257b5
72
pep-0386.txt
72
pep-0386.txt
|
@ -76,11 +76,12 @@ considered important semantics:
|
|||
1. it should be possible to express more than one versioning level
|
||||
(usually this is expressed as major and minor revision and, sometimes,
|
||||
also a micro revision).
|
||||
2. most projects need special meaning versions for "pre-releases" (such as
|
||||
"alpha", "beta", "rc"), and these have widely used aliases ("a" stands
|
||||
for "alpha", "b" for "beta" and "c" for "rc"). And these pre-release
|
||||
versions make it impossible to use a simple alphanumerical ordering
|
||||
of the version string components. (Example: 3.1a1 < 3.1)
|
||||
2. a significant number of projects need special meaning versions for
|
||||
"pre-releases" (such as "alpha", "beta", "rc"), and these have widely
|
||||
used aliases ("a" stands for "alpha", "b" for "beta" and "c" for "rc").
|
||||
And these pre-release versions make it impossible to use a simple
|
||||
alphanumerical ordering of the version string components.
|
||||
(Example: 3.1a1 < 3.1)
|
||||
3. some projects also need "post-releases" of regular versions,
|
||||
mainly for installer work which can't be clearly expressed otherwise.
|
||||
4. development versions allow packagers of unreleased work to avoid version
|
||||
|
@ -307,7 +308,7 @@ The real regular expression is::
|
|||
|
||||
Some examples probably make it clearer::
|
||||
|
||||
>>> from verlib import RationalVersion as V
|
||||
>>> from verlib import NormalizedVersion as V
|
||||
>>> (V('1.0a1')
|
||||
... < V('1.0a2.dev456')
|
||||
... < V('1.0a2')
|
||||
|
@ -334,18 +335,18 @@ Last, ``.post456.dev34`` indicates a dev marker for a post release, that sorts
|
|||
before a ``.post456`` marker. This can be used to do development versions
|
||||
of post releases.
|
||||
|
||||
``verlib`` provides a ``RationalVersion`` class and a
|
||||
``suggest_rational_version`` function.
|
||||
``verlib`` provides a ``NormalizedVersion`` class and a
|
||||
``suggest_normalized_version`` function.
|
||||
|
||||
RationalVersion
|
||||
---------------
|
||||
NormalizedVersion
|
||||
-----------------
|
||||
|
||||
The `RationalVersion` class is used to hold a version and to compare it with
|
||||
The `NormalizedVersion` class is used to hold a version and to compare it with
|
||||
others. It takes a string as an argument, that contains the representation of
|
||||
the version::
|
||||
|
||||
>>> from verlib import RationalVersion
|
||||
>>> version = RationalVersion('1.0')
|
||||
>>> from verlib import NormalizedVersion
|
||||
>>> version = NormalizedVersion('1.0')
|
||||
|
||||
The version can be represented as a string::
|
||||
|
||||
|
@ -354,9 +355,9 @@ The version can be represented as a string::
|
|||
|
||||
Or compared with others::
|
||||
|
||||
>>> RationalVersion('1.0') > RationalVersion('0.9')
|
||||
>>> NormalizedVersion('1.0') > NormalizedVersion('0.9')
|
||||
True
|
||||
>>> RationalVersion('1.0') < RationalVersion('1.1')
|
||||
>>> NormalizedVersion('1.0') < NormalizedVersion('1.1')
|
||||
True
|
||||
|
||||
A class method called ``from_parts`` is available if you want to create an
|
||||
|
@ -364,63 +365,64 @@ instance by providing the parts that composes the version.
|
|||
|
||||
Examples ::
|
||||
|
||||
>>> version = RationalVersion.from_parts((1, 0))
|
||||
>>> version = NormalizedVersion.from_parts((1, 0))
|
||||
>>> str(version)
|
||||
'1.0'
|
||||
|
||||
>>> version = RationalVersion.from_parts((1, 0), ('c', 4))
|
||||
>>> version = NormalizedVersion.from_parts((1, 0), ('c', 4))
|
||||
>>> str(version)
|
||||
'1.0c4'
|
||||
|
||||
>>> version = RationalVersion.from_parts((1, 0), ('c', 4), ('dev', 34))
|
||||
>>> version = NormalizedVersion.from_parts((1, 0), ('c', 4), ('dev', 34))
|
||||
>>> str(version)
|
||||
'1.0c4.dev34'
|
||||
|
||||
|
||||
suggest_rational_version
|
||||
------------------------
|
||||
suggest_normalized_version
|
||||
--------------------------
|
||||
|
||||
``suggest_rational_version`` is a function that suggests a rational version
|
||||
``suggest_normalized_version`` is a function that suggests a normalized version
|
||||
close to the given version string. If you have a version string that isn't
|
||||
rational (i.e. ``RationalVersion`` doesn't like it) then you might be able
|
||||
to get an equivalent (or close) rational version from this function.
|
||||
normalized (i.e. ``NormalizedVersion`` doesn't like it) then you might be able
|
||||
to get an equivalent (or close) normalized version from this function.
|
||||
|
||||
This does a number of simple normalizations to the given string, based
|
||||
on observation of versions currently in use on PyPI. Given a dump of those
|
||||
version during PyCon 2009, 4287 of them:
|
||||
|
||||
- 2312 (53.93%) match RationalVersion without change with the automatic
|
||||
- 2312 (53.93%) match NormalizedVersion without change with the automatic
|
||||
suggestion
|
||||
- 3474 (81.04%) match when using this suggestion method
|
||||
|
||||
When a tool needs to work with versions, a strategy is to use
|
||||
``suggest_rational_version`` on the versions string. If this function returns
|
||||
``suggest_normalized_version`` on the versions string. If this function returns
|
||||
``None``, it means that the provided version is not close enough to the
|
||||
standard scheme. If it returns a version that slighlty differs from
|
||||
the original version, it's a suggested rational version. Last, if it
|
||||
the original version, it's a suggested normalized version. Last, if it
|
||||
returns the same string, it means that the version matches the scheme.
|
||||
|
||||
Here's an example of usage ::
|
||||
|
||||
>>> from verlib import suggest_rational_version, RationalVersion
|
||||
>>> from verlib import suggest_normalized_version, NormalizedVersion
|
||||
>>> import warnings
|
||||
>>> def validate_version(version):
|
||||
... rversion = suggest_rational_version(version)
|
||||
... rversion = suggest_normalized_version(version)
|
||||
... if rversion is None:
|
||||
... raise ValueError('Cannot work with "%s"' % version)
|
||||
... if rversion != version:
|
||||
... warnings.warn('"%s" is not a rational version, '
|
||||
... 'it has been transformed into "%s" '
|
||||
... warnings.warn('"%s" is not a normalized version.\n'
|
||||
... 'It has been transformed into "%s" '
|
||||
... 'for interoperability.' % (version, rversion))
|
||||
... return RationalVersion(rversion)
|
||||
... return NormalizedVersion(rversion)
|
||||
...
|
||||
|
||||
>>> validate_version('2.4rc1')
|
||||
__main__:8: UserWarning: "2.4rc1" is not a rational version, it has been transformed into "2.4c1" for interoperability.
|
||||
RationalVersion('2.4c1')
|
||||
__main__:8: UserWarning: "2.4rc1" is not a normalized version.
|
||||
It has been transformed into "2.4c1" for interoperability.
|
||||
NormalizedVersion('2.4c1')
|
||||
|
||||
>>> validate_version('2.4c1')
|
||||
RationalVersion('2.4c1')
|
||||
NormalizedVersion('2.4c1')
|
||||
|
||||
>>> validate_version('foo')
|
||||
Traceback (most recent call last):
|
||||
|
@ -432,7 +434,7 @@ Roadmap
|
|||
=======
|
||||
|
||||
Distutils will deprecate its existing versions class in favor of
|
||||
``RationalVersion``. The ``verlib`` module presented in this PEP will be
|
||||
``NormalizedVersion``. The ``verlib`` module presented in this PEP will be
|
||||
renamed to ``version`` and placed into the ``distutils`` package.
|
||||
|
||||
References
|
||||
|
|
Loading…
Reference in New Issue