_version_info.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. # SPDX-License-Identifier: MIT
  2. from functools import total_ordering
  3. from ._funcs import astuple
  4. from ._make import attrib, attrs
  5. @total_ordering
  6. @attrs(eq=False, order=False, slots=True, frozen=True)
  7. class VersionInfo:
  8. """
  9. A version object that can be compared to tuple of length 1--4:
  10. >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2)
  11. True
  12. >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1)
  13. True
  14. >>> vi = attr.VersionInfo(19, 2, 0, "final")
  15. >>> vi < (19, 1, 1)
  16. False
  17. >>> vi < (19,)
  18. False
  19. >>> vi == (19, 2,)
  20. True
  21. >>> vi == (19, 2, 1)
  22. False
  23. .. versionadded:: 19.2
  24. """
  25. year = attrib(type=int)
  26. minor = attrib(type=int)
  27. micro = attrib(type=int)
  28. releaselevel = attrib(type=str)
  29. @classmethod
  30. def _from_version_string(cls, s):
  31. """
  32. Parse *s* and return a _VersionInfo.
  33. """
  34. v = s.split(".")
  35. if len(v) == 3:
  36. v.append("final")
  37. return cls(
  38. year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3]
  39. )
  40. def _ensure_tuple(self, other):
  41. """
  42. Ensure *other* is a tuple of a valid length.
  43. Returns a possibly transformed *other* and ourselves as a tuple of
  44. the same length as *other*.
  45. """
  46. if self.__class__ is other.__class__:
  47. other = astuple(other)
  48. if not isinstance(other, tuple):
  49. raise NotImplementedError
  50. if not (1 <= len(other) <= 4):
  51. raise NotImplementedError
  52. return astuple(self)[: len(other)], other
  53. def __eq__(self, other):
  54. try:
  55. us, them = self._ensure_tuple(other)
  56. except NotImplementedError:
  57. return NotImplemented
  58. return us == them
  59. def __lt__(self, other):
  60. try:
  61. us, them = self._ensure_tuple(other)
  62. except NotImplementedError:
  63. return NotImplemented
  64. # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't
  65. # have to do anything special with releaselevel for now.
  66. return us < them