1 """Generate and work with PEP 425 Compatibility Tags.
5 from typing import List, Optional, Tuple
7 from pip._vendor.packaging.tags import (
18 _osx_arch_pat = re.compile(r"(.+)_(\d+)_(\d+)_(.+)")
21 def version_info_to_nodot(version_info: Tuple[int, ...]) -> str:
22 # Only use up to the first two numbers.
23 return "".join(map(str, version_info[:2]))
26 def _mac_platforms(arch: str) -> List[str]:
27 match = _osx_arch_pat.match(arch)
29 name, major, minor, actual_arch = match.groups()
30 mac_version = (int(major), int(minor))
32 # Since we have always only checked that the platform starts
33 # with "macosx", for backwards-compatibility we extract the
34 # actual prefix provided by the user in case they provided
35 # something like "macosxcustom_". It may be good to remove
36 # this as undocumented or deprecate it in the future.
37 "{}_{}".format(name, arch[len("macosx_") :])
38 for arch in mac_platforms(mac_version, actual_arch)
41 # arch pattern didn't match (?!)
46 def _custom_manylinux_platforms(arch: str) -> List[str]:
48 arch_prefix, arch_sep, arch_suffix = arch.partition("_")
49 if arch_prefix == "manylinux2014":
50 # manylinux1/manylinux2010 wheels run on most manylinux2014 systems
51 # with the exception of wheels depending on ncurses. PEP 599 states
52 # manylinux1/manylinux2010 wheels should be considered
53 # manylinux2014 wheels:
54 # https://www.python.org/dev/peps/pep-0599/#backwards-compatibility-with-manylinux2010-wheels
55 if arch_suffix in {"i686", "x86_64"}:
56 arches.append("manylinux2010" + arch_sep + arch_suffix)
57 arches.append("manylinux1" + arch_sep + arch_suffix)
58 elif arch_prefix == "manylinux2010":
59 # manylinux1 wheels run on most manylinux2010 systems with the
60 # exception of wheels depending on ncurses. PEP 571 states
61 # manylinux1 wheels should be considered manylinux2010 wheels:
62 # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels
63 arches.append("manylinux1" + arch_sep + arch_suffix)
67 def _get_custom_platforms(arch: str) -> List[str]:
68 arch_prefix, arch_sep, arch_suffix = arch.partition("_")
69 if arch.startswith("macosx"):
70 arches = _mac_platforms(arch)
71 elif arch_prefix in ["manylinux2014", "manylinux2010"]:
72 arches = _custom_manylinux_platforms(arch)
78 def _expand_allowed_platforms(platforms: Optional[List[str]]) -> Optional[List[str]]:
88 additions = [c for c in _get_custom_platforms(p) if c not in seen]
89 seen.update(additions)
90 result.extend(additions)
95 def _get_python_version(version: str) -> PythonVersion:
97 return int(version[0]), int(version[1:])
99 return (int(version[0]),)
102 def _get_custom_interpreter(
103 implementation: Optional[str] = None, version: Optional[str] = None
105 if implementation is None:
106 implementation = interpreter_name()
108 version = interpreter_version()
109 return f"{implementation}{version}"
113 version: Optional[str] = None,
114 platforms: Optional[List[str]] = None,
115 impl: Optional[str] = None,
116 abis: Optional[List[str]] = None,
118 """Return a list of supported tags for each version specified in
121 :param version: a string version, of the form "33" or "32",
122 or None. The version will be assumed to support our ABI.
123 :param platform: specify a list of platforms you want valid
124 tags for, or None. If None, use the local system platform.
125 :param impl: specify the exact implementation you want valid
126 tags for, or None. If None, use the local interpreter impl.
127 :param abis: specify a list of abis you want valid
128 tags for, or None. If None, use the local interpreter abi.
130 supported: List[Tag] = []
132 python_version: Optional[PythonVersion] = None
133 if version is not None:
134 python_version = _get_python_version(version)
136 interpreter = _get_custom_interpreter(impl, version)
138 platforms = _expand_allowed_platforms(platforms)
140 is_cpython = (impl or interpreter_name()) == "cp"
144 python_version=python_version,
152 interpreter=interpreter,
159 python_version=python_version,
160 interpreter=interpreter,