aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/distutils/version.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/distutils/version.py')
-rw-r--r--Lib/distutils/version.py124
1 files changed, 87 insertions, 37 deletions
diff --git a/Lib/distutils/version.py b/Lib/distutils/version.py
index 0fb5b6e2041..ebcab84e4e2 100644
--- a/Lib/distutils/version.py
+++ b/Lib/distutils/version.py
@@ -21,18 +21,18 @@ Every version number class implements the following interface:
an equivalent string -- ie. one that will generate an equivalent
version number instance)
* __repr__ generates Python code to recreate the version number instance
- * __cmp__ compares the current instance with either another instance
+ * _cmp compares the current instance with either another instance
of the same class or a string (which will be parsed to an instance
of the same class, thus must follow the same rules)
"""
-import string, re
-from types import StringType
+import re
class Version:
"""Abstract base class for version numbering classes. Just provides
constructor (__init__) and reproducer (__repr__), because those
- seem to be the same for all version numbering classes.
+ seem to be the same for all version numbering classes; and route
+ rich comparisons to _cmp.
"""
def __init__ (self, vstring=None):
@@ -42,6 +42,42 @@ class Version:
def __repr__ (self):
return "%s ('%s')" % (self.__class__.__name__, str(self))
+ def __eq__(self, other):
+ c = self._cmp(other)
+ if c is NotImplemented:
+ return c
+ return c == 0
+
+ def __ne__(self, other):
+ c = self._cmp(other)
+ if c is NotImplemented:
+ return c
+ return c != 0
+
+ def __lt__(self, other):
+ c = self._cmp(other)
+ if c is NotImplemented:
+ return c
+ return c < 0
+
+ def __le__(self, other):
+ c = self._cmp(other)
+ if c is NotImplemented:
+ return c
+ return c <= 0
+
+ def __gt__(self, other):
+ c = self._cmp(other)
+ if c is NotImplemented:
+ return c
+ return c > 0
+
+ def __ge__(self, other):
+ c = self._cmp(other)
+ if c is NotImplemented:
+ return c
+ return c >= 0
+
# Interface for version-number classes -- must be implemented
# by the following classes (the concrete ones -- Version should
@@ -55,7 +91,7 @@ class Version:
# (if not identical to) the string supplied to parse
# __repr__ (self) - generate Python code to recreate
# the instance
-# __cmp__ (self, other) - compare two version numbers ('other' may
+# _cmp (self, other) - compare two version numbers ('other' may
# be an unparsed version string, or another
# instance of your version class)
@@ -98,24 +134,24 @@ class StrictVersion (Version):
"""
version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$',
- re.VERBOSE)
+ re.VERBOSE | re.ASCII)
def parse (self, vstring):
match = self.version_re.match(vstring)
if not match:
- raise ValueError, "invalid version number '%s'" % vstring
+ raise ValueError("invalid version number '%s'" % vstring)
(major, minor, patch, prerelease, prerelease_num) = \
match.group(1, 2, 4, 5, 6)
if patch:
- self.version = tuple(map(string.atoi, [major, minor, patch]))
+ self.version = tuple(map(int, [major, minor, patch]))
else:
- self.version = tuple(map(string.atoi, [major, minor]) + [0])
+ self.version = tuple(map(int, [major, minor])) + (0,)
if prerelease:
- self.prerelease = (prerelease[0], string.atoi(prerelease_num))
+ self.prerelease = (prerelease[0], int(prerelease_num))
else:
self.prerelease = None
@@ -123,9 +159,9 @@ class StrictVersion (Version):
def __str__ (self):
if self.version[2] == 0:
- vstring = string.join(map(str, self.version[0:2]), '.')
+ vstring = '.'.join(map(str, self.version[0:2]))
else:
- vstring = string.join(map(str, self.version), '.')
+ vstring = '.'.join(map(str, self.version))
if self.prerelease:
vstring = vstring + self.prerelease[0] + str(self.prerelease[1])
@@ -133,30 +169,39 @@ class StrictVersion (Version):
return vstring
- def __cmp__ (self, other):
- if isinstance(other, StringType):
+ def _cmp (self, other):
+ if isinstance(other, str):
other = StrictVersion(other)
- compare = cmp(self.version, other.version)
- if (compare == 0): # have to compare prerelease
-
- # case 1: neither has prerelease; they're equal
- # case 2: self has prerelease, other doesn't; other is greater
- # case 3: self doesn't have prerelease, other does: self is greater
- # case 4: both have prerelease: must compare them!
+ if self.version != other.version:
+ # numeric versions don't match
+ # prerelease stuff doesn't matter
+ if self.version < other.version:
+ return -1
+ else:
+ return 1
- if (not self.prerelease and not other.prerelease):
+ # have to compare prerelease
+ # case 1: neither has prerelease; they're equal
+ # case 2: self has prerelease, other doesn't; other is greater
+ # case 3: self doesn't have prerelease, other does: self is greater
+ # case 4: both have prerelease: must compare them!
+
+ if (not self.prerelease and not other.prerelease):
+ return 0
+ elif (self.prerelease and not other.prerelease):
+ return -1
+ elif (not self.prerelease and other.prerelease):
+ return 1
+ elif (self.prerelease and other.prerelease):
+ if self.prerelease == other.prerelease:
return 0
- elif (self.prerelease and not other.prerelease):
+ elif self.prerelease < other.prerelease:
return -1
- elif (not self.prerelease and other.prerelease):
+ else:
return 1
- elif (self.prerelease and other.prerelease):
- return cmp(self.prerelease, other.prerelease)
-
- else: # numeric versions don't match --
- return compare # prerelease stuff doesn't matter
-
+ else:
+ assert False, "never get here"
# end class StrictVersion
@@ -270,11 +315,11 @@ class LooseVersion (Version):
# from the parsed tuple -- so I just store the string here for
# use by __str__
self.vstring = vstring
- components = filter(lambda x: x and x != '.',
- self.component_re.split(vstring))
- for i in range(len(components)):
+ components = [x for x in self.component_re.split(vstring)
+ if x and x != '.']
+ for i, obj in enumerate(components):
try:
- components[i] = int(components[i])
+ components[i] = int(obj)
except ValueError:
pass
@@ -289,11 +334,16 @@ class LooseVersion (Version):
return "LooseVersion ('%s')" % str(self)
- def __cmp__ (self, other):
- if isinstance(other, StringType):
+ def _cmp (self, other):
+ if isinstance(other, str):
other = LooseVersion(other)
- return cmp(self.version, other.version)
+ if self.version == other.version:
+ return 0
+ if self.version < other.version:
+ return -1
+ if self.version > other.version:
+ return 1
# end class LooseVersion