codekingpro/portable-devtools
114k
1# SPDX-License-Identifier: MIT2 3 4from functools import total_ordering5 6from ._funcs import astuple7from ._make import attrib, attrs8 9 10@total_ordering11@attrs(eq=False, order=False, slots=True, frozen=True)12class VersionInfo:13 """14 A version object that can be compared to tuple of length 1--4:15 16 >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2)17 True18 >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1)19 True20 >>> vi = attr.VersionInfo(19, 2, 0, "final")21 >>> vi < (19, 1, 1)22 False23 >>> vi < (19,)24 False25 >>> vi == (19, 2,)26 True27 >>> vi == (19, 2, 1)28 False29 30 .. versionadded:: 19.231 """32 33 year = attrib(type=int)34 minor = attrib(type=int)35 micro = attrib(type=int)36 releaselevel = attrib(type=str)37 38 @classmethod39 def _from_version_string(cls, s):40 """41 Parse *s* and return a _VersionInfo.42 """43 v = s.split(".")44 if len(v) == 3:45 v.append("final")46 47 return cls(48 year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3]49 )50 51 def _ensure_tuple(self, other):52 """53 Ensure *other* is a tuple of a valid length.54 55 Returns a possibly transformed *other* and ourselves as a tuple of56 the same length as *other*.57 """58 59 if self.__class__ is other.__class__:60 other = astuple(other)61 62 if not isinstance(other, tuple):63 raise NotImplementedError64 65 if not (1 <= len(other) <= 4):66 raise NotImplementedError67 68 return astuple(self)[: len(other)], other69 70 def __eq__(self, other):71 try:72 us, them = self._ensure_tuple(other)73 except NotImplementedError:74 return NotImplemented75 76 return us == them77 78 def __lt__(self, other):79 try:80 us, them = self._ensure_tuple(other)81 except NotImplementedError:82 return NotImplemented83 84 # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't85 # have to do anything special with releaselevel for now.86 return us < them87 88 def __hash__(self):89 return hash((self.year, self.minor, self.micro, self.releaselevel))90 