diff options
Diffstat (limited to 'Lib/distutils/version.py')
-rw-r--r-- | Lib/distutils/version.py | 124 |
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 |