'Rational' becomes 'Normalized'

This commit is contained in:
Tarek Ziadé 2009-12-13 11:47:36 +00:00
parent 60035e5912
commit af0f8257b5
1 changed files with 37 additions and 35 deletions

View File

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