| """Generate and work with PEP 425 Compatibility Tags. |
| """ |
| |
| from __future__ import absolute_import |
| |
| import re |
| |
| from pip._vendor.packaging.tags import ( |
| Tag, |
| compatible_tags, |
| cpython_tags, |
| generic_tags, |
| interpreter_name, |
| interpreter_version, |
| mac_platforms, |
| ) |
| |
| from pip._internal.utils.typing import MYPY_CHECK_RUNNING |
| |
| if MYPY_CHECK_RUNNING: |
| from typing import List, Optional, Tuple |
| |
| from pip._vendor.packaging.tags import PythonVersion |
| |
| _osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') |
| |
| |
| def version_info_to_nodot(version_info): |
| # type: (Tuple[int, ...]) -> str |
| # Only use up to the first two numbers. |
| return ''.join(map(str, version_info[:2])) |
| |
| |
| def _mac_platforms(arch): |
| # type: (str) -> List[str] |
| match = _osx_arch_pat.match(arch) |
| if match: |
| name, major, minor, actual_arch = match.groups() |
| mac_version = (int(major), int(minor)) |
| arches = [ |
| # Since we have always only checked that the platform starts |
| # with "macosx", for backwards-compatibility we extract the |
| # actual prefix provided by the user in case they provided |
| # something like "macosxcustom_". It may be good to remove |
| # this as undocumented or deprecate it in the future. |
| '{}_{}'.format(name, arch[len('macosx_'):]) |
| for arch in mac_platforms(mac_version, actual_arch) |
| ] |
| else: |
| # arch pattern didn't match (?!) |
| arches = [arch] |
| return arches |
| |
| |
| def _custom_manylinux_platforms(arch): |
| # type: (str) -> List[str] |
| arches = [arch] |
| arch_prefix, arch_sep, arch_suffix = arch.partition('_') |
| if arch_prefix == 'manylinux2014': |
| # manylinux1/manylinux2010 wheels run on most manylinux2014 systems |
| # with the exception of wheels depending on ncurses. PEP 599 states |
| # manylinux1/manylinux2010 wheels should be considered |
| # manylinux2014 wheels: |
| # https://www.python.org/dev/peps/pep-0599/#backwards-compatibility-with-manylinux2010-wheels |
| if arch_suffix in {'i686', 'x86_64'}: |
| arches.append('manylinux2010' + arch_sep + arch_suffix) |
| arches.append('manylinux1' + arch_sep + arch_suffix) |
| elif arch_prefix == 'manylinux2010': |
| # manylinux1 wheels run on most manylinux2010 systems with the |
| # exception of wheels depending on ncurses. PEP 571 states |
| # manylinux1 wheels should be considered manylinux2010 wheels: |
| # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels |
| arches.append('manylinux1' + arch_sep + arch_suffix) |
| return arches |
| |
| |
| def _get_custom_platforms(arch): |
| # type: (str) -> List[str] |
| arch_prefix, arch_sep, arch_suffix = arch.partition('_') |
| if arch.startswith('macosx'): |
| arches = _mac_platforms(arch) |
| elif arch_prefix in ['manylinux2014', 'manylinux2010']: |
| arches = _custom_manylinux_platforms(arch) |
| else: |
| arches = [arch] |
| return arches |
| |
| |
| def _get_python_version(version): |
| # type: (str) -> PythonVersion |
| if len(version) > 1: |
| return int(version[0]), int(version[1:]) |
| else: |
| return (int(version[0]),) |
| |
| |
| def _get_custom_interpreter(implementation=None, version=None): |
| # type: (Optional[str], Optional[str]) -> str |
| if implementation is None: |
| implementation = interpreter_name() |
| if version is None: |
| version = interpreter_version() |
| return "{}{}".format(implementation, version) |
| |
| |
| def get_supported( |
| version=None, # type: Optional[str] |
| platform=None, # type: Optional[str] |
| impl=None, # type: Optional[str] |
| abi=None # type: Optional[str] |
| ): |
| # type: (...) -> List[Tag] |
| """Return a list of supported tags for each version specified in |
| `versions`. |
| |
| :param version: a string version, of the form "33" or "32", |
| or None. The version will be assumed to support our ABI. |
| :param platform: specify the exact platform you want valid |
| tags for, or None. If None, use the local system platform. |
| :param impl: specify the exact implementation you want valid |
| tags for, or None. If None, use the local interpreter impl. |
| :param abi: specify the exact abi you want valid |
| tags for, or None. If None, use the local interpreter abi. |
| """ |
| supported = [] # type: List[Tag] |
| |
| python_version = None # type: Optional[PythonVersion] |
| if version is not None: |
| python_version = _get_python_version(version) |
| |
| interpreter = _get_custom_interpreter(impl, version) |
| |
| abis = None # type: Optional[List[str]] |
| if abi is not None: |
| abis = [abi] |
| |
| platforms = None # type: Optional[List[str]] |
| if platform is not None: |
| platforms = _get_custom_platforms(platform) |
| |
| is_cpython = (impl or interpreter_name()) == "cp" |
| if is_cpython: |
| supported.extend( |
| cpython_tags( |
| python_version=python_version, |
| abis=abis, |
| platforms=platforms, |
| ) |
| ) |
| else: |
| supported.extend( |
| generic_tags( |
| interpreter=interpreter, |
| abis=abis, |
| platforms=platforms, |
| ) |
| ) |
| supported.extend( |
| compatible_tags( |
| python_version=python_version, |
| interpreter=interpreter, |
| platforms=platforms, |
| ) |
| ) |
| |
| return supported |