_version_info.py 2.1 KB

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