@@ -22,14 +22,19 @@ def _cmp(a, b):
2222
2323
2424def cmp_pkg_version (version_str , pkg_version_str = __version__ ):
25- """ Compare `version_str` to current package version
25+ """ Compare `` version_str` ` to current package version
2626
2727 To be valid, a version must have a numerical major version followed by a
2828 dot, followed by a numerical minor version. It may optionally be followed
2929 by a dot and a numerical micro version, and / or by an "extra" string.
30- *Any* extra string labels the version as pre-release, so `1.2.0somestring`
31- compares as prior to (pre-release for) `1.2.0`, where `somestring` can be
32- any string.
30+ The extra string may further contain a "+". Any value to the left of a "+"
31+ labels the version as pre-release, while values to the right indicate a
32+ post-release relative to the values to the left. That is,
33+ ``1.2.0+1`` is post-release for ``1.2.0``, while ``1.2.0rc1+1`` is
34+ post-release for ``1.2.0rc1`` and pre-release for ``1.2.0``.
35+
36+ This is an approximation of `PEP-440`_, and future versions will fully
37+ implement PEP-440.
3338
3439 Parameters
3540 ----------
@@ -50,19 +55,38 @@ def cmp_pkg_version(version_str, pkg_version_str=__version__):
5055 1
5156 >>> cmp_pkg_version('1.2.0dev', '1.2.0')
5257 -1
58+ >>> cmp_pkg_version('1.2.0dev', '1.2.0rc1')
59+ -1
60+ >>> cmp_pkg_version('1.2.0rc1', '1.2.0')
61+ -1
62+ >>> cmp_pkg_version('1.2.0rc1+1', '1.2.0rc1')
63+ 1
64+ >>> cmp_pkg_version('1.2.0rc1+1', '1.2.0')
65+ -1
66+
67+ .. _`PEP-440`: https://www.python.org/dev/peps/pep-0440/
5368 """
5469 version , extra = _parse_version (version_str )
5570 pkg_version , pkg_extra = _parse_version (pkg_version_str )
56- if version != pkg_version :
57- return _cmp (StrictVersion (version ), StrictVersion (pkg_version ))
58- if extra .startswith ('+' ) or pkg_extra .startswith ('+' ):
59- return (1 if pkg_extra == ''
60- else - 1 if extra == ''
61- else _cmp (extra , pkg_extra ))
62- return (0 if extra == pkg_extra
63- else 1 if extra == ''
64- else - 1 if pkg_extra == ''
65- else _cmp (extra , pkg_extra ))
71+
72+ # Normalize versions
73+ quick_check = _cmp (StrictVersion (version ), StrictVersion (pkg_version ))
74+ # Nothing further to check
75+ if quick_check != 0 or extra == pkg_extra == '' :
76+ return quick_check
77+
78+ # Before + is pre-release, after + is additional increment
79+ pre , _ , post = extra .partition ('+' )
80+ pkg_pre , _ , pkg_post = pkg_extra .partition ('+' )
81+ quick_check = _cmp (pre , pkg_pre )
82+ if quick_check != 0 : # Excludes case where pre and pkg_pre == ''
83+ # Pre-releases are ordered but strictly less than non-pre
84+ return (1 if pre == ''
85+ else - 1 if pkg_pre == ''
86+ else quick_check )
87+
88+ # All else being equal, compare additional information lexically
89+ return _cmp (post , pkg_post )
6690
6791
6892def pkg_commit_hash (pkg_path = None ):
0 commit comments