utils.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. # This file is dual licensed under the terms of the Apache License, Version
  2. # 2.0, and the BSD License. See the LICENSE file in the root of this repository
  3. # for complete details.
  4. from __future__ import absolute_import, division, print_function
  5. import re
  6. from ._typing import TYPE_CHECKING, cast
  7. from .version import InvalidVersion, Version
  8. if TYPE_CHECKING: # pragma: no cover
  9. from typing import NewType, Union
  10. NormalizedName = NewType("NormalizedName", str)
  11. else:
  12. NormalizedName = str
  13. _canonicalize_regex = re.compile(r"[-_.]+")
  14. def canonicalize_name(name):
  15. # type: (str) -> NormalizedName
  16. # This is taken from PEP 503.
  17. value = _canonicalize_regex.sub("-", name).lower()
  18. return cast("NormalizedName", value)
  19. def canonicalize_version(version):
  20. # type: (Union[Version, str]) -> Union[Version, str]
  21. """
  22. This is very similar to Version.__str__, but has one subtle difference
  23. with the way it handles the release segment.
  24. """
  25. if not isinstance(version, Version):
  26. try:
  27. version = Version(version)
  28. except InvalidVersion:
  29. # Legacy versions cannot be normalized
  30. return version
  31. parts = []
  32. # Epoch
  33. if version.epoch != 0:
  34. parts.append("{0}!".format(version.epoch))
  35. # Release segment
  36. # NB: This strips trailing '.0's to normalize
  37. parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in version.release)))
  38. # Pre-release
  39. if version.pre is not None:
  40. parts.append("".join(str(x) for x in version.pre))
  41. # Post-release
  42. if version.post is not None:
  43. parts.append(".post{0}".format(version.post))
  44. # Development release
  45. if version.dev is not None:
  46. parts.append(".dev{0}".format(version.dev))
  47. # Local version segment
  48. if version.local is not None:
  49. parts.append("+{0}".format(version.local))
  50. return "".join(parts)