wheel.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. """Represents a wheel file and provides access to the various parts of the
  2. name that have meaning.
  3. """
  4. import re
  5. from pip._vendor.packaging.tags import Tag
  6. from pip._internal.exceptions import InvalidWheelFilename
  7. from pip._internal.utils.typing import MYPY_CHECK_RUNNING
  8. if MYPY_CHECK_RUNNING:
  9. from typing import List
  10. class Wheel(object):
  11. """A wheel file"""
  12. wheel_file_re = re.compile(
  13. r"""^(?P<namever>(?P<name>.+?)-(?P<ver>.*?))
  14. ((-(?P<build>\d[^-]*?))?-(?P<pyver>.+?)-(?P<abi>.+?)-(?P<plat>.+?)
  15. \.whl|\.dist-info)$""",
  16. re.VERBOSE
  17. )
  18. def __init__(self, filename):
  19. # type: (str) -> None
  20. """
  21. :raises InvalidWheelFilename: when the filename is invalid for a wheel
  22. """
  23. wheel_info = self.wheel_file_re.match(filename)
  24. if not wheel_info:
  25. raise InvalidWheelFilename(
  26. "{} is not a valid wheel filename.".format(filename)
  27. )
  28. self.filename = filename
  29. self.name = wheel_info.group('name').replace('_', '-')
  30. # we'll assume "_" means "-" due to wheel naming scheme
  31. # (https://github.com/pypa/pip/issues/1150)
  32. self.version = wheel_info.group('ver').replace('_', '-')
  33. self.build_tag = wheel_info.group('build')
  34. self.pyversions = wheel_info.group('pyver').split('.')
  35. self.abis = wheel_info.group('abi').split('.')
  36. self.plats = wheel_info.group('plat').split('.')
  37. # All the tag combinations from this file
  38. self.file_tags = {
  39. Tag(x, y, z) for x in self.pyversions
  40. for y in self.abis for z in self.plats
  41. }
  42. def get_formatted_file_tags(self):
  43. # type: () -> List[str]
  44. """Return the wheel's tags as a sorted list of strings."""
  45. return sorted(str(tag) for tag in self.file_tags)
  46. def support_index_min(self, tags):
  47. # type: (List[Tag]) -> int
  48. """Return the lowest index that one of the wheel's file_tag combinations
  49. achieves in the given list of supported tags.
  50. For example, if there are 8 supported tags and one of the file tags
  51. is first in the list, then return 0.
  52. :param tags: the PEP 425 tags to check the wheel against, in order
  53. with most preferred first.
  54. :raises ValueError: If none of the wheel's file tags match one of
  55. the supported tags.
  56. """
  57. return min(tags.index(tag) for tag in self.file_tags if tag in tags)
  58. def supported(self, tags):
  59. # type: (List[Tag]) -> bool
  60. """Return whether the wheel is compatible with one of the given tags.
  61. :param tags: the PEP 425 tags to check the wheel against.
  62. """
  63. return not self.file_tags.isdisjoint(tags)