From 3ada01fb51fdbc168e04a15f8eac1b77542e19d2 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:27 -0500 Subject: [PATCH 01/34] Convert return values in pep425tags.get_supported Now we can incrementally use utility functions from pep425tags without switching everything at once or converting in multiple places. --- src/pip/_internal/pep425tags.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 7b7a3551b71..dc0aaed6533 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -313,7 +313,7 @@ def get_supported( :param abi: specify the exact abi you want valid tags for, or None. If None, use the local interpreter abi. """ - supported = [] + supported = [] # type: List[Union[Tag, Tuple[str, str, str]]] # Versions must be given with respect to the preference if version is None: @@ -368,4 +368,7 @@ def get_supported( for version in other_versions: supported.append(('py%s' % (version,), 'none', 'any')) - return [Tag(*parts) for parts in supported] + return [ + parts if isinstance(parts, Tag) else Tag(*parts) + for parts in supported + ] From d386bb2fffd1af7d164da44556190cbde83e8146 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:28 -0500 Subject: [PATCH 02/34] Copy get_supported into packaging.tags-like functions packaging.tags provides a simple `sys_tags` function for getting applicable tags for the running interpreter, but it does not allow customization of arguments. packaging.tags provides three functions for getting custom tags: 1. `cpython_tags` - for CPython only 2. `generic_tags` - for any non-CPython Python implementation 3. `compatible_tags` - tags that are not specific to an interpreter implementation Since pip allows users to provide explicit impl, platform, abi, and version, we have to use these functions. `cpython_tags` and `generic_tags` are mutually exclusive, and return tags that are the highest priority. These capture the most specific tags. `compatible_tags` are always applicable, and a lower priority since they may just be compatible with e.g. the Python language version, but lack any optimizations available in the interpreter-specific tags. To be able to do a meaningful comparison between our current implementation and the above functions, we need to segment the pip code into pieces that look like them. To that end, we now have copies of the current `get_supported` function, one for each of the functions provided by packaging.tags, and will walk through converting them to rely on packaging.tags. For each simplification step, if desired, we can compare the implementation in the packaging.tags function with what we're replacing in pip. Specifically, for each function in turn, we will: 1. Refactor it locally, taking into account its new, more limited, responsibilities 2. Introduce the packaging.tags function for the case where there are no custom arguments provided 3. Customize arguments one-by-one and delegate to the packaging.tags function 4. When there is no pip-specific logic left, remove the intermediate function and use the packaging.tags function directly in `get_supported` In the end all these functions will be gone again and we'll be left with an implementation that relies solely on the tag generation in packaging.tags. --- src/pip/_internal/pep425tags.py | 195 ++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index dc0aaed6533..915f5bcf19e 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -294,6 +294,201 @@ def _get_custom_platforms(arch, platform): return arches +def _cpython_tags( + version=None, # type: Optional[str] + platform=None, # type: Optional[str] + impl=None, # type: Optional[str] + abi=None, # type: Optional[str] +): + # type: (...) -> List[Tuple[str, str, str]] + supported = [] # type: List[Tuple[str, str, str]] + + # Versions must be given with respect to the preference + if version is None: + version_info = get_impl_version_info() + versions = get_all_minor_versions_as_strings(version_info) + else: + versions = [version] + current_version = versions[0] + other_versions = versions[1:] + + impl = impl or interpreter_name() + + abis = [] # type: List[str] + + abi = abi or get_abi_tag() + if abi: + abis[0:0] = [abi] + + supports_abi3 = not PY2 and impl == "cp" + + if supports_abi3: + abis.append("abi3") + + abis.append('none') + + arches = _get_custom_platforms(platform or get_platform(), platform) + + # Current version, current API (built specifically for our Python): + for abi in abis: + for arch in arches: + supported.append(('%s%s' % (impl, current_version), abi, arch)) + + # abi3 modules compatible with older version of Python + if supports_abi3: + for version in other_versions: + # abi3 was introduced in Python 3.2 + if version in {'31', '30'}: + break + for arch in arches: + supported.append(("%s%s" % (impl, version), "abi3", arch)) + + # Has binaries, does not use the Python API: + for arch in arches: + supported.append(('py%s' % (current_version[0]), 'none', arch)) + + # No abi / arch, but requires our implementation: + supported.append(('%s%s' % (impl, current_version), 'none', 'any')) + + # No abi / arch, generic Python + supported.append(('py%s' % (current_version,), 'none', 'any')) + supported.append(('py%s' % (current_version[0]), 'none', 'any')) + for version in other_versions: + supported.append(('py%s' % (version,), 'none', 'any')) + + return supported + + +def _generic_tags( + version=None, # type: Optional[str] + platform=None, # type: Optional[str] + impl=None, # type: Optional[str] + abi=None, # type: Optional[str] +): + # type: (...) -> List[Tuple[str, str, str]] + supported = [] # type: List[Tuple[str, str, str]] + + # Versions must be given with respect to the preference + if version is None: + version_info = get_impl_version_info() + versions = get_all_minor_versions_as_strings(version_info) + else: + versions = [version] + current_version = versions[0] + other_versions = versions[1:] + + impl = impl or interpreter_name() + + abis = [] # type: List[str] + + abi = abi or get_abi_tag() + if abi: + abis[0:0] = [abi] + + supports_abi3 = not PY2 and impl == "cp" + + if supports_abi3: + abis.append("abi3") + + abis.append('none') + + arches = _get_custom_platforms(platform or get_platform(), platform) + + # Current version, current API (built specifically for our Python): + for abi in abis: + for arch in arches: + supported.append(('%s%s' % (impl, current_version), abi, arch)) + + # abi3 modules compatible with older version of Python + if supports_abi3: + for version in other_versions: + # abi3 was introduced in Python 3.2 + if version in {'31', '30'}: + break + for arch in arches: + supported.append(("%s%s" % (impl, version), "abi3", arch)) + + # Has binaries, does not use the Python API: + for arch in arches: + supported.append(('py%s' % (current_version[0]), 'none', arch)) + + # No abi / arch, but requires our implementation: + supported.append(('%s%s' % (impl, current_version), 'none', 'any')) + + # No abi / arch, generic Python + supported.append(('py%s' % (current_version,), 'none', 'any')) + supported.append(('py%s' % (current_version[0]), 'none', 'any')) + for version in other_versions: + supported.append(('py%s' % (version,), 'none', 'any')) + + return supported + + +def _compatible_tags( + version=None, # type: Optional[str] + platform=None, # type: Optional[str] + impl=None, # type: Optional[str] + abi=None, # type: Optional[str] +): + # type: (...) -> List[Tuple[str, str, str]] + supported = [] # type: List[Tuple[str, str, str]] + + # Versions must be given with respect to the preference + if version is None: + version_info = get_impl_version_info() + versions = get_all_minor_versions_as_strings(version_info) + else: + versions = [version] + current_version = versions[0] + other_versions = versions[1:] + + impl = impl or interpreter_name() + + abis = [] # type: List[str] + + abi = abi or get_abi_tag() + if abi: + abis[0:0] = [abi] + + supports_abi3 = not PY2 and impl == "cp" + + if supports_abi3: + abis.append("abi3") + + abis.append('none') + + arches = _get_custom_platforms(platform or get_platform(), platform) + + # Current version, current API (built specifically for our Python): + for abi in abis: + for arch in arches: + supported.append(('%s%s' % (impl, current_version), abi, arch)) + + # abi3 modules compatible with older version of Python + if supports_abi3: + for version in other_versions: + # abi3 was introduced in Python 3.2 + if version in {'31', '30'}: + break + for arch in arches: + supported.append(("%s%s" % (impl, version), "abi3", arch)) + + # Has binaries, does not use the Python API: + for arch in arches: + supported.append(('py%s' % (current_version[0]), 'none', arch)) + + # No abi / arch, but requires our implementation: + supported.append(('%s%s' % (impl, current_version), 'none', 'any')) + + # No abi / arch, generic Python + supported.append(('py%s' % (current_version,), 'none', 'any')) + supported.append(('py%s' % (current_version[0]), 'none', 'any')) + for version in other_versions: + supported.append(('py%s' % (version,), 'none', 'any')) + + return supported + + def get_supported( version=None, # type: Optional[str] platform=None, # type: Optional[str] From 54db17c976084edf98113aa5401ecf1c9418d018 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:29 -0500 Subject: [PATCH 03/34] Use _cpython_tags, _generic_tags, and _compatible_tags Since these functions are copies of the existing code, there is no behavior change except each tag will now be present 3 times. To accommodate this we remove all but the first duplicate tag from the set of all tags. We put `_compatible_tags` last because it will provide the lowest priority tags. The order of `_cpython_tags` and `_generic_tags` here is not significant - when we start customizing them we will introduce a condition so that they are mutually exclusive. --- src/pip/_internal/pep425tags.py | 69 +++++++-------------------------- 1 file changed, 15 insertions(+), 54 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 915f5bcf19e..2a021418de4 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -21,7 +21,7 @@ if MYPY_CHECK_RUNNING: from typing import ( - Callable, List, Optional, Tuple, Union + Callable, Iterator, List, Optional, Set, Tuple, Union ) logger = logging.getLogger(__name__) @@ -489,6 +489,15 @@ def _compatible_tags( return supported +def _stable_unique_tags(tags): + # type: (List[Tag]) -> Iterator[Tag] + observed = set() # type: Set[Tag] + for tag in tags: + if tag not in observed: + observed.add(tag) + yield tag + + def get_supported( version=None, # type: Optional[str] platform=None, # type: Optional[str] @@ -510,60 +519,12 @@ def get_supported( """ supported = [] # type: List[Union[Tag, Tuple[str, str, str]]] - # Versions must be given with respect to the preference - if version is None: - version_info = get_impl_version_info() - versions = get_all_minor_versions_as_strings(version_info) - else: - versions = [version] - current_version = versions[0] - other_versions = versions[1:] - - impl = impl or interpreter_name() - - abis = [] # type: List[str] - - abi = abi or get_abi_tag() - if abi: - abis[0:0] = [abi] - - supports_abi3 = not PY2 and impl == "cp" - - if supports_abi3: - abis.append("abi3") - - abis.append('none') - - arches = _get_custom_platforms(platform or get_platform(), platform) - - # Current version, current API (built specifically for our Python): - for abi in abis: - for arch in arches: - supported.append(('%s%s' % (impl, current_version), abi, arch)) - - # abi3 modules compatible with older version of Python - if supports_abi3: - for version in other_versions: - # abi3 was introduced in Python 3.2 - if version in {'31', '30'}: - break - for arch in arches: - supported.append(("%s%s" % (impl, version), "abi3", arch)) - - # Has binaries, does not use the Python API: - for arch in arches: - supported.append(('py%s' % (current_version[0]), 'none', arch)) - - # No abi / arch, but requires our implementation: - supported.append(('%s%s' % (impl, current_version), 'none', 'any')) - - # No abi / arch, generic Python - supported.append(('py%s' % (current_version,), 'none', 'any')) - supported.append(('py%s' % (current_version[0]), 'none', 'any')) - for version in other_versions: - supported.append(('py%s' % (version,), 'none', 'any')) + supported.extend(_cpython_tags(version, platform, impl, abi)) + supported.extend(_generic_tags(version, platform, impl, abi)) + supported.extend(_compatible_tags(version, platform, impl, abi)) - return [ + tags = [ parts if isinstance(parts, Tag) else Tag(*parts) for parts in supported ] + return list(_stable_unique_tags(tags)) From 1c8c481214f89df6ea50659646f537388c80ea2d Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:30 -0500 Subject: [PATCH 04/34] Only calculate py-compatible tags in one place Since `_compatible_tags` is the function that will be responsible for generating the non-interpreter-specific tags, we remove the corresponding sections from `_cpython_tags` and `_generic_tags`. The resulting tags in `get_supported` are equivalent because these were the last tags to be computed in those functions, and `_compatible_tags` is executed after them (so any non-duplicate tags it produces will be last). To reinforce the reponsibility of `_compatible_tags` we also remove the abi-related tag generation, which is already handled in `_cpython_tags` and `_generic_tags`. --- src/pip/_internal/pep425tags.py | 53 --------------------------------- 1 file changed, 53 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 2a021418de4..99a2fc29623 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -343,19 +343,6 @@ def _cpython_tags( for arch in arches: supported.append(("%s%s" % (impl, version), "abi3", arch)) - # Has binaries, does not use the Python API: - for arch in arches: - supported.append(('py%s' % (current_version[0]), 'none', arch)) - - # No abi / arch, but requires our implementation: - supported.append(('%s%s' % (impl, current_version), 'none', 'any')) - - # No abi / arch, generic Python - supported.append(('py%s' % (current_version,), 'none', 'any')) - supported.append(('py%s' % (current_version[0]), 'none', 'any')) - for version in other_versions: - supported.append(('py%s' % (version,), 'none', 'any')) - return supported @@ -408,19 +395,6 @@ def _generic_tags( for arch in arches: supported.append(("%s%s" % (impl, version), "abi3", arch)) - # Has binaries, does not use the Python API: - for arch in arches: - supported.append(('py%s' % (current_version[0]), 'none', arch)) - - # No abi / arch, but requires our implementation: - supported.append(('%s%s' % (impl, current_version), 'none', 'any')) - - # No abi / arch, generic Python - supported.append(('py%s' % (current_version,), 'none', 'any')) - supported.append(('py%s' % (current_version[0]), 'none', 'any')) - for version in other_versions: - supported.append(('py%s' % (version,), 'none', 'any')) - return supported @@ -444,35 +418,8 @@ def _compatible_tags( impl = impl or interpreter_name() - abis = [] # type: List[str] - - abi = abi or get_abi_tag() - if abi: - abis[0:0] = [abi] - - supports_abi3 = not PY2 and impl == "cp" - - if supports_abi3: - abis.append("abi3") - - abis.append('none') - arches = _get_custom_platforms(platform or get_platform(), platform) - # Current version, current API (built specifically for our Python): - for abi in abis: - for arch in arches: - supported.append(('%s%s' % (impl, current_version), abi, arch)) - - # abi3 modules compatible with older version of Python - if supports_abi3: - for version in other_versions: - # abi3 was introduced in Python 3.2 - if version in {'31', '30'}: - break - for arch in arches: - supported.append(("%s%s" % (impl, version), "abi3", arch)) - # Has binaries, does not use the Python API: for arch in arches: supported.append(('py%s' % (current_version[0]), 'none', arch)) From 480911bc8e943f38bda692da7757b0fdea221670 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:31 -0500 Subject: [PATCH 05/34] Remove unused abi arg from _compatible_tags --- src/pip/_internal/pep425tags.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 99a2fc29623..d2c72954427 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -402,7 +402,6 @@ def _compatible_tags( version=None, # type: Optional[str] platform=None, # type: Optional[str] impl=None, # type: Optional[str] - abi=None, # type: Optional[str] ): # type: (...) -> List[Tuple[str, str, str]] supported = [] # type: List[Tuple[str, str, str]] @@ -468,7 +467,7 @@ def get_supported( supported.extend(_cpython_tags(version, platform, impl, abi)) supported.extend(_generic_tags(version, platform, impl, abi)) - supported.extend(_compatible_tags(version, platform, impl, abi)) + supported.extend(_compatible_tags(version, platform, impl)) tags = [ parts if isinstance(parts, Tag) else Tag(*parts) From 4659a78935533b90ea0e2211890a968b05c52994 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:32 -0500 Subject: [PATCH 06/34] Use packaging.tags.compatible_tags We assume this function improves on our existing behavior, so use it as-is. We will customize the arguments over the next few commits. Since packaging.tags internally calculates platforms when not provided, we skip the tests which patch functions assuming that manylinux compatibility determination depends on them. --- src/pip/_internal/pep425tags.py | 6 +++++- tests/unit/test_pep425tags.py | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index d2c72954427..21c58593f15 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -10,6 +10,7 @@ from pip._vendor.packaging.tags import ( Tag, + compatible_tags, interpreter_name, interpreter_version, mac_platforms, @@ -403,7 +404,10 @@ def _compatible_tags( platform=None, # type: Optional[str] impl=None, # type: Optional[str] ): - # type: (...) -> List[Tuple[str, str, str]] + # type: (...) -> Union[Iterator[Tag], List[Tuple[str, str, str]]] + if version is None and platform is None and impl is None: + return compatible_tags() + supported = [] # type: List[Tuple[str, str, str]] # Versions must be given with respect to the preference diff --git a/tests/unit/test_pep425tags.py b/tests/unit/test_pep425tags.py index eaa88888fb0..58e97a3e85e 100644 --- a/tests/unit/test_pep425tags.py +++ b/tests/unit/test_pep425tags.py @@ -170,6 +170,7 @@ def test_manylinux_3(self, is_manylinux_compatible): class TestManylinux1Tags(object): + @pytest.mark.xfail @patch('pip._internal.pep425tags.is_manylinux2010_compatible', lambda: False) @patch('pip._internal.pep425tags.is_manylinux2014_compatible', @@ -200,6 +201,7 @@ def test_manylinux1_tag_is_first(self): class TestManylinux2010Tags(object): + @pytest.mark.xfail @patch('pip._internal.pep425tags.is_manylinux2014_compatible', lambda: False) @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64') @@ -253,6 +255,7 @@ def test_manylinux2010_implies_manylinux1(self, manylinux2010, manylinux1): class TestManylinux2014Tags(object): + @pytest.mark.xfail @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64') @patch('pip._internal.utils.glibc.have_compatible_glibc', lambda major, minor: True) From 750abcab041d136231036bdc5153d4976d4a83bf Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:33 -0500 Subject: [PATCH 07/34] Customize python_version for packaging.tags.compatible_tags --- src/pip/_internal/pep425tags.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 21c58593f15..59fa9d8d1d5 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -25,6 +25,8 @@ Callable, Iterator, List, Optional, Set, Tuple, Union ) + from pip._vendor.packaging.tags import PythonVersion + logger = logging.getLogger(__name__) _osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') @@ -295,6 +297,14 @@ def _get_custom_platforms(arch, platform): 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 _cpython_tags( version=None, # type: Optional[str] platform=None, # type: Optional[str] @@ -405,8 +415,12 @@ def _compatible_tags( impl=None, # type: Optional[str] ): # type: (...) -> Union[Iterator[Tag], List[Tuple[str, str, str]]] - if version is None and platform is None and impl is None: - return compatible_tags() + python_version = None # type: Optional[PythonVersion] + if version is not None: + python_version = _get_python_version(version) + + if platform is None and impl is None: + return compatible_tags(python_version=python_version) supported = [] # type: List[Tuple[str, str, str]] From 72d00ddcc1eb927de9355215f5fbc935654dc12a Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:34 -0500 Subject: [PATCH 08/34] Customize interpreter for packaging.tags.compatible_tags --- src/pip/_internal/pep425tags.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 59fa9d8d1d5..044f7a01a15 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -305,6 +305,15 @@ def _get_python_version(version): 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 _cpython_tags( version=None, # type: Optional[str] platform=None, # type: Optional[str] @@ -419,8 +428,13 @@ def _compatible_tags( if version is not None: python_version = _get_python_version(version) - if platform is None and impl is None: - return compatible_tags(python_version=python_version) + interpreter = _get_custom_interpreter(impl, version) + + if platform is None: + return compatible_tags( + python_version=python_version, + interpreter=interpreter, + ) supported = [] # type: List[Tuple[str, str, str]] From 2de0b7c560e3fc910ebdddebb708d2f9430dce69 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:35 -0500 Subject: [PATCH 09/34] Customize platforms for packaging.tags.compatible_tags --- src/pip/_internal/pep425tags.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 044f7a01a15..0ef93d008b7 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -430,10 +430,15 @@ def _compatible_tags( interpreter = _get_custom_interpreter(impl, version) - if platform is None: + platforms = None # type: Optional[List[str]] + if platform is not None: + platforms = _get_custom_platforms(platform, platform) + + if True: return compatible_tags( python_version=python_version, interpreter=interpreter, + platforms=platforms, ) supported = [] # type: List[Tuple[str, str, str]] From c514c6b35f3f277e0f12add0f238b5e11c3e9715 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:36 -0500 Subject: [PATCH 10/34] Make packaging.tags.compatible_tags unconditional --- src/pip/_internal/pep425tags.py | 43 +++++---------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 0ef93d008b7..482e37b6211 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -423,7 +423,7 @@ def _compatible_tags( platform=None, # type: Optional[str] impl=None, # type: Optional[str] ): - # type: (...) -> Union[Iterator[Tag], List[Tuple[str, str, str]]] + # type: (...) -> Iterator[Tag] python_version = None # type: Optional[PythonVersion] if version is not None: python_version = _get_python_version(version) @@ -434,42 +434,11 @@ def _compatible_tags( if platform is not None: platforms = _get_custom_platforms(platform, platform) - if True: - return compatible_tags( - python_version=python_version, - interpreter=interpreter, - platforms=platforms, - ) - - supported = [] # type: List[Tuple[str, str, str]] - - # Versions must be given with respect to the preference - if version is None: - version_info = get_impl_version_info() - versions = get_all_minor_versions_as_strings(version_info) - else: - versions = [version] - current_version = versions[0] - other_versions = versions[1:] - - impl = impl or interpreter_name() - - arches = _get_custom_platforms(platform or get_platform(), platform) - - # Has binaries, does not use the Python API: - for arch in arches: - supported.append(('py%s' % (current_version[0]), 'none', arch)) - - # No abi / arch, but requires our implementation: - supported.append(('%s%s' % (impl, current_version), 'none', 'any')) - - # No abi / arch, generic Python - supported.append(('py%s' % (current_version,), 'none', 'any')) - supported.append(('py%s' % (current_version[0]), 'none', 'any')) - for version in other_versions: - supported.append(('py%s' % (version,), 'none', 'any')) - - return supported + return compatible_tags( + python_version=python_version, + interpreter=interpreter, + platforms=platforms, + ) def _stable_unique_tags(tags): From b91286c38d0c871b7d15f000e80b2c74235e19ad Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:37 -0500 Subject: [PATCH 11/34] Inline packaging.tags.compatible_tags --- src/pip/_internal/pep425tags.py | 41 ++++++++++++++------------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 482e37b6211..26721b92feb 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -418,29 +418,6 @@ def _generic_tags( return supported -def _compatible_tags( - version=None, # type: Optional[str] - platform=None, # type: Optional[str] - impl=None, # type: Optional[str] -): - # type: (...) -> Iterator[Tag] - python_version = None # type: Optional[PythonVersion] - if version is not None: - python_version = _get_python_version(version) - - interpreter = _get_custom_interpreter(impl, version) - - platforms = None # type: Optional[List[str]] - if platform is not None: - platforms = _get_custom_platforms(platform, platform) - - return compatible_tags( - python_version=python_version, - interpreter=interpreter, - platforms=platforms, - ) - - def _stable_unique_tags(tags): # type: (List[Tag]) -> Iterator[Tag] observed = set() # type: Set[Tag] @@ -471,9 +448,25 @@ def get_supported( """ supported = [] # type: List[Union[Tag, Tuple[str, str, str]]] + python_version = None # type: Optional[PythonVersion] + if version is not None: + python_version = _get_python_version(version) + + interpreter = _get_custom_interpreter(impl, version) + + platforms = None # type: Optional[List[str]] + if platform is not None: + platforms = _get_custom_platforms(platform, platform) + supported.extend(_cpython_tags(version, platform, impl, abi)) supported.extend(_generic_tags(version, platform, impl, abi)) - supported.extend(_compatible_tags(version, platform, impl)) + supported.extend( + compatible_tags( + python_version=python_version, + interpreter=interpreter, + platforms=platforms, + ) + ) tags = [ parts if isinstance(parts, Tag) else Tag(*parts) From 8f1c60ead06238773f8f6827767ef835c641b636 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:38 -0500 Subject: [PATCH 12/34] Only use _cpython_tags for CPython Since the behavior for both of these functions is the same, there is no behavior change here. This will let us simplify `_cpython_tags` a bit. --- src/pip/_internal/pep425tags.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 26721b92feb..b5017605100 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -458,8 +458,11 @@ def get_supported( if platform is not None: platforms = _get_custom_platforms(platform, platform) - supported.extend(_cpython_tags(version, platform, impl, abi)) - supported.extend(_generic_tags(version, platform, impl, abi)) + is_cpython = (impl or interpreter_name()) == "cp" + if is_cpython: + supported.extend(_cpython_tags(version, platform, impl, abi)) + else: + supported.extend(_generic_tags(version, platform, impl, abi)) supported.extend( compatible_tags( python_version=python_version, From e388df6c594267e8e3ad9c033325965d5bcf3603 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:39 -0500 Subject: [PATCH 13/34] Remove impl from _cpython_tags We only call this function when the user or platform-provided implementation is "cp", so we can inline the literal in place of the parameter. This will make refactoring easier. --- src/pip/_internal/pep425tags.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index b5017605100..be61646a004 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -317,7 +317,6 @@ def _get_custom_interpreter(implementation=None, version=None): def _cpython_tags( version=None, # type: Optional[str] platform=None, # type: Optional[str] - impl=None, # type: Optional[str] abi=None, # type: Optional[str] ): # type: (...) -> List[Tuple[str, str, str]] @@ -332,15 +331,13 @@ def _cpython_tags( current_version = versions[0] other_versions = versions[1:] - impl = impl or interpreter_name() - abis = [] # type: List[str] abi = abi or get_abi_tag() if abi: abis[0:0] = [abi] - supports_abi3 = not PY2 and impl == "cp" + supports_abi3 = not PY2 if supports_abi3: abis.append("abi3") @@ -352,7 +349,7 @@ def _cpython_tags( # Current version, current API (built specifically for our Python): for abi in abis: for arch in arches: - supported.append(('%s%s' % (impl, current_version), abi, arch)) + supported.append(('cp%s' % current_version, abi, arch)) # abi3 modules compatible with older version of Python if supports_abi3: @@ -361,7 +358,7 @@ def _cpython_tags( if version in {'31', '30'}: break for arch in arches: - supported.append(("%s%s" % (impl, version), "abi3", arch)) + supported.append(("cp%s" % version, "abi3", arch)) return supported @@ -460,7 +457,7 @@ def get_supported( is_cpython = (impl or interpreter_name()) == "cp" if is_cpython: - supported.extend(_cpython_tags(version, platform, impl, abi)) + supported.extend(_cpython_tags(version, platform, abi)) else: supported.extend(_generic_tags(version, platform, impl, abi)) supported.extend( From 5dbef5debecc1677472dcbfa26f76f2db1896af2 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:41 -0500 Subject: [PATCH 14/34] Use packaging.tags.cpython_tags We assume this function improves the status quo over the current `_cpython_tags`, so we use it when no arguments need to be customized. Since `packaging.tags` has its own tests and derives defaults differently than pep425tags, we also remove the applicable tests that were testing against the result of a plain call to `pep425tags.get_supported()`. --- src/pip/_internal/pep425tags.py | 6 ++- tests/unit/test_pep425tags.py | 93 --------------------------------- 2 files changed, 5 insertions(+), 94 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index be61646a004..7804766f4c7 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -11,6 +11,7 @@ from pip._vendor.packaging.tags import ( Tag, compatible_tags, + cpython_tags, interpreter_name, interpreter_version, mac_platforms, @@ -319,7 +320,10 @@ def _cpython_tags( platform=None, # type: Optional[str] abi=None, # type: Optional[str] ): - # type: (...) -> List[Tuple[str, str, str]] + # type: (...) -> Union[Iterator[Tag], List[Tuple[str, str, str]]] + if version is None and platform is None and abi is None: + return cpython_tags() + supported = [] # type: List[Tuple[str, str, str]] # Versions must be given with respect to the preference diff --git a/tests/unit/test_pep425tags.py b/tests/unit/test_pep425tags.py index 58e97a3e85e..a5469725e96 100644 --- a/tests/unit/test_pep425tags.py +++ b/tests/unit/test_pep425tags.py @@ -168,70 +168,8 @@ def test_manylinux_3(self, is_manylinux_compatible): assert not is_manylinux_compatible() -class TestManylinux1Tags(object): - - @pytest.mark.xfail - @patch('pip._internal.pep425tags.is_manylinux2010_compatible', - lambda: False) - @patch('pip._internal.pep425tags.is_manylinux2014_compatible', - lambda: False) - @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: True) - @patch('sys.platform', 'linux2') - def test_manylinux1_tag_is_first(self): - """ - Test that the more specific tag manylinux1 comes first. - """ - groups = {} - for tag in pep425tags.get_supported(): - groups.setdefault( - (tag.interpreter, tag.abi), [] - ).append(tag.platform) - - for arches in groups.values(): - if arches == ['any']: - continue - # Expect the most specific arch first: - if len(arches) == 3: - assert arches == ['manylinux1_x86_64', 'linux_x86_64', 'any'] - else: - assert arches == ['manylinux1_x86_64', 'linux_x86_64'] - - class TestManylinux2010Tags(object): - @pytest.mark.xfail - @patch('pip._internal.pep425tags.is_manylinux2014_compatible', - lambda: False) - @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: True) - @patch('sys.platform', 'linux2') - def test_manylinux2010_tag_is_first(self): - """ - Test that the more specific tag manylinux2010 comes first. - """ - groups = {} - for tag in pep425tags.get_supported(): - groups.setdefault( - (tag.interpreter, tag.abi), [] - ).append(tag.platform) - - for arches in groups.values(): - if arches == ['any']: - continue - # Expect the most specific arch first: - if len(arches) == 4: - assert arches == ['manylinux2010_x86_64', - 'manylinux1_x86_64', - 'linux_x86_64', - 'any'] - else: - assert arches == ['manylinux2010_x86_64', - 'manylinux1_x86_64', - 'linux_x86_64'] - @pytest.mark.parametrize("manylinux2010,manylinux1", [ ("manylinux2010_x86_64", "manylinux1_x86_64"), ("manylinux2010_i686", "manylinux1_i686"), @@ -255,37 +193,6 @@ def test_manylinux2010_implies_manylinux1(self, manylinux2010, manylinux1): class TestManylinux2014Tags(object): - @pytest.mark.xfail - @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: True) - @patch('sys.platform', 'linux2') - def test_manylinux2014_tag_is_first(self): - """ - Test that the more specific tag manylinux2014 comes first. - """ - groups = {} - for tag in pep425tags.get_supported(): - groups.setdefault( - (tag.interpreter, tag.abi), [] - ).append(tag.platform) - - for arches in groups.values(): - if arches == ['any']: - continue - # Expect the most specific arch first: - if len(arches) == 5: - assert arches == ['manylinux2014_x86_64', - 'manylinux2010_x86_64', - 'manylinux1_x86_64', - 'linux_x86_64', - 'any'] - else: - assert arches == ['manylinux2014_x86_64', - 'manylinux2010_x86_64', - 'manylinux1_x86_64', - 'linux_x86_64'] - @pytest.mark.parametrize("manylinuxA,manylinuxB", [ ("manylinux2014_x86_64", ["manylinux2010_x86_64", "manylinux1_x86_64"]), From 147680a6134a6eabbae64715d93adda555d0738a Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:42 -0500 Subject: [PATCH 15/34] Customize python_version for packaging.tags.cpython_tags --- src/pip/_internal/pep425tags.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 7804766f4c7..0f5f7ceef94 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -321,8 +321,12 @@ def _cpython_tags( abi=None, # type: Optional[str] ): # type: (...) -> Union[Iterator[Tag], List[Tuple[str, str, str]]] - if version is None and platform is None and abi is None: - return cpython_tags() + python_version = None # type: Optional[PythonVersion] + if version is not None: + python_version = _get_python_version(version) + + if platform is None and abi is None: + return cpython_tags(python_version=python_version) supported = [] # type: List[Tuple[str, str, str]] From 05045e790324ebc63c9bc714ab3d2f76589a2fa0 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:43 -0500 Subject: [PATCH 16/34] Customize abis for packaging.tags.cpython_tags --- src/pip/_internal/pep425tags.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 0f5f7ceef94..2c90790567c 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -325,8 +325,12 @@ def _cpython_tags( if version is not None: python_version = _get_python_version(version) - if platform is None and abi is None: - return cpython_tags(python_version=python_version) + abis = None # type: Optional[List[str]] + if abi is not None: + abis = [abi] + + if platform is None: + return cpython_tags(python_version=python_version, abis=abis) supported = [] # type: List[Tuple[str, str, str]] @@ -339,7 +343,7 @@ def _cpython_tags( current_version = versions[0] other_versions = versions[1:] - abis = [] # type: List[str] + abis = [] # type: ignore # we will be removing this soon abi = abi or get_abi_tag() if abi: From fecfadb8100d679862600e506dfd2436a5bbb125 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:44 -0500 Subject: [PATCH 17/34] Customize platforms for packaging.tags.cpython_tags --- src/pip/_internal/pep425tags.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 2c90790567c..a841acf45cc 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -329,8 +329,16 @@ def _cpython_tags( if abi is not None: abis = [abi] - if platform is None: - return cpython_tags(python_version=python_version, abis=abis) + platforms = None # type: Optional[List[str]] + if platform is not None: + platforms = _get_custom_platforms(platform, platform) + + if True: + return cpython_tags( + python_version=python_version, + abis=abis, + platforms=platforms, + ) supported = [] # type: List[Tuple[str, str, str]] From 56840c30c5d897691b14ddc9d8979f82bc981539 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:45 -0500 Subject: [PATCH 18/34] Make packaging.tags.cpython_tags unconditional --- src/pip/_internal/pep425tags.py | 55 ++++----------------------------- 1 file changed, 6 insertions(+), 49 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index a841acf45cc..309c5a3d987 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -320,7 +320,7 @@ def _cpython_tags( platform=None, # type: Optional[str] abi=None, # type: Optional[str] ): - # type: (...) -> Union[Iterator[Tag], List[Tuple[str, str, str]]] + # type: (...) -> Iterator[Tag] python_version = None # type: Optional[PythonVersion] if version is not None: python_version = _get_python_version(version) @@ -333,54 +333,11 @@ def _cpython_tags( if platform is not None: platforms = _get_custom_platforms(platform, platform) - if True: - return cpython_tags( - python_version=python_version, - abis=abis, - platforms=platforms, - ) - - supported = [] # type: List[Tuple[str, str, str]] - - # Versions must be given with respect to the preference - if version is None: - version_info = get_impl_version_info() - versions = get_all_minor_versions_as_strings(version_info) - else: - versions = [version] - current_version = versions[0] - other_versions = versions[1:] - - abis = [] # type: ignore # we will be removing this soon - - abi = abi or get_abi_tag() - if abi: - abis[0:0] = [abi] - - supports_abi3 = not PY2 - - if supports_abi3: - abis.append("abi3") - - abis.append('none') - - arches = _get_custom_platforms(platform or get_platform(), platform) - - # Current version, current API (built specifically for our Python): - for abi in abis: - for arch in arches: - supported.append(('cp%s' % current_version, abi, arch)) - - # abi3 modules compatible with older version of Python - if supports_abi3: - for version in other_versions: - # abi3 was introduced in Python 3.2 - if version in {'31', '30'}: - break - for arch in arches: - supported.append(("cp%s" % version, "abi3", arch)) - - return supported + return cpython_tags( + python_version=python_version, + abis=abis, + platforms=platforms, + ) def _generic_tags( From 1574872162f3310f98367cb19ef6e28f0ef60bf7 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:46 -0500 Subject: [PATCH 19/34] Inline packaging.tags.cpython_tags --- src/pip/_internal/pep425tags.py | 37 ++++++++++----------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 309c5a3d987..2f205d7390e 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -315,31 +315,6 @@ def _get_custom_interpreter(implementation=None, version=None): return "{}{}".format(implementation, version) -def _cpython_tags( - version=None, # type: Optional[str] - platform=None, # type: Optional[str] - abi=None, # type: Optional[str] -): - # type: (...) -> Iterator[Tag] - python_version = None # type: Optional[PythonVersion] - if version is not None: - python_version = _get_python_version(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, platform) - - return cpython_tags( - python_version=python_version, - abis=abis, - platforms=platforms, - ) - - def _generic_tags( version=None, # type: Optional[str] platform=None, # type: Optional[str] @@ -428,13 +403,23 @@ def get_supported( 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, platform) is_cpython = (impl or interpreter_name()) == "cp" if is_cpython: - supported.extend(_cpython_tags(version, platform, abi)) + supported.extend( + cpython_tags( + python_version=python_version, + abis=abis, + platforms=platforms, + ) + ) else: supported.extend(_generic_tags(version, platform, impl, abi)) supported.extend( From fa1ec40ce01a67c97ccee44a44b451542a0fd674 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:47 -0500 Subject: [PATCH 20/34] Remove unused abi3 branch in _generic_tags Since this function is only called for non-CPython interpreters, the abi3-related branches are not relevant. --- src/pip/_internal/pep425tags.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 2f205d7390e..25e6ddd1aeb 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -16,7 +16,6 @@ interpreter_version, mac_platforms, ) -from pip._vendor.six import PY2 import pip._internal.utils.glibc from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -331,7 +330,6 @@ def _generic_tags( else: versions = [version] current_version = versions[0] - other_versions = versions[1:] impl = impl or interpreter_name() @@ -341,11 +339,6 @@ def _generic_tags( if abi: abis[0:0] = [abi] - supports_abi3 = not PY2 and impl == "cp" - - if supports_abi3: - abis.append("abi3") - abis.append('none') arches = _get_custom_platforms(platform or get_platform(), platform) @@ -355,15 +348,6 @@ def _generic_tags( for arch in arches: supported.append(('%s%s' % (impl, current_version), abi, arch)) - # abi3 modules compatible with older version of Python - if supports_abi3: - for version in other_versions: - # abi3 was introduced in Python 3.2 - if version in {'31', '30'}: - break - for arch in arches: - supported.append(("%s%s" % (impl, version), "abi3", arch)) - return supported From 281273dac3d66273e6ffc43522122680cc13e40a Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:48 -0500 Subject: [PATCH 21/34] Use packaging.tags.generic_tags As with cpython_tags and compatible_tags, we assume this function covers our use cases in the no-argument case and will customize our arguments for it in a few steps. --- src/pip/_internal/pep425tags.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 25e6ddd1aeb..08179deca2a 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -12,6 +12,7 @@ Tag, compatible_tags, cpython_tags, + generic_tags, interpreter_name, interpreter_version, mac_platforms, @@ -320,7 +321,10 @@ def _generic_tags( impl=None, # type: Optional[str] abi=None, # type: Optional[str] ): - # type: (...) -> List[Tuple[str, str, str]] + # type: (...) -> Union[Iterator[Tag], List[Tuple[str, str, str]]] + if version is None and platform is None and impl is None and abi is None: + return generic_tags() + supported = [] # type: List[Tuple[str, str, str]] # Versions must be given with respect to the preference From 77dbd27703e1dce568af1eff7ffd7cc77189639e Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:49 -0500 Subject: [PATCH 22/34] Customize interpreter for packaging.tags.generic_tags --- src/pip/_internal/pep425tags.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 08179deca2a..db8af9c9dc2 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -322,8 +322,10 @@ def _generic_tags( abi=None, # type: Optional[str] ): # type: (...) -> Union[Iterator[Tag], List[Tuple[str, str, str]]] - if version is None and platform is None and impl is None and abi is None: - return generic_tags() + interpreter = _get_custom_interpreter(impl, version) + + if platform is None and abi is None: + return generic_tags(interpreter=interpreter) supported = [] # type: List[Tuple[str, str, str]] From 0bebeb66e6b33c5d191b40de121f36c83dee6dbd Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:50 -0500 Subject: [PATCH 23/34] Customize abis for packaging.tags.generic_tags --- src/pip/_internal/pep425tags.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index db8af9c9dc2..f14ed8c35cc 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -324,8 +324,12 @@ def _generic_tags( # type: (...) -> Union[Iterator[Tag], List[Tuple[str, str, str]]] interpreter = _get_custom_interpreter(impl, version) - if platform is None and abi is None: - return generic_tags(interpreter=interpreter) + abis = None # type: Optional[List[str]] + if abi: + abis = [abi] + + if platform is None: + return generic_tags(interpreter=interpreter, abis=abis) supported = [] # type: List[Tuple[str, str, str]] @@ -339,7 +343,7 @@ def _generic_tags( impl = impl or interpreter_name() - abis = [] # type: List[str] + abis = [] # type: ignore # we will be removing this soon abi = abi or get_abi_tag() if abi: From 293b778374bf7ce9db650adb7e73a9ec96884ba4 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:51 -0500 Subject: [PATCH 24/34] Customize platforms for packaging.tags.generic_tags --- src/pip/_internal/pep425tags.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index f14ed8c35cc..8194b584023 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -328,8 +328,16 @@ def _generic_tags( if abi: abis = [abi] - if platform is None: - return generic_tags(interpreter=interpreter, abis=abis) + platforms = None # type: Optional[List[str]] + if platform is not None: + platforms = _get_custom_platforms(platform, platform) + + if True: + return generic_tags( + interpreter=interpreter, + abis=abis, + platforms=platforms, + ) supported = [] # type: List[Tuple[str, str, str]] From 72dcd34eb214e7df95de3a8f49bb76750fbd5952 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:52 -0500 Subject: [PATCH 25/34] Make packaging.tags.generic_tags unconditional --- src/pip/_internal/pep425tags.py | 42 +++++---------------------------- 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 8194b584023..bbfff6ba87c 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -321,7 +321,7 @@ def _generic_tags( impl=None, # type: Optional[str] abi=None, # type: Optional[str] ): - # type: (...) -> Union[Iterator[Tag], List[Tuple[str, str, str]]] + # type: (...) -> Iterator[Tag] interpreter = _get_custom_interpreter(impl, version) abis = None # type: Optional[List[str]] @@ -332,41 +332,11 @@ def _generic_tags( if platform is not None: platforms = _get_custom_platforms(platform, platform) - if True: - return generic_tags( - interpreter=interpreter, - abis=abis, - platforms=platforms, - ) - - supported = [] # type: List[Tuple[str, str, str]] - - # Versions must be given with respect to the preference - if version is None: - version_info = get_impl_version_info() - versions = get_all_minor_versions_as_strings(version_info) - else: - versions = [version] - current_version = versions[0] - - impl = impl or interpreter_name() - - abis = [] # type: ignore # we will be removing this soon - - abi = abi or get_abi_tag() - if abi: - abis[0:0] = [abi] - - abis.append('none') - - arches = _get_custom_platforms(platform or get_platform(), platform) - - # Current version, current API (built specifically for our Python): - for abi in abis: - for arch in arches: - supported.append(('%s%s' % (impl, current_version), abi, arch)) - - return supported + return generic_tags( + interpreter=interpreter, + abis=abis, + platforms=platforms, + ) def _stable_unique_tags(tags): From 3e66ab0918dfd89f74b1c87b05675e6f29e97e03 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:53 -0500 Subject: [PATCH 26/34] Inline packaging.tags.generic_tags --- src/pip/_internal/pep425tags.py | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index bbfff6ba87c..38ac99aa388 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -315,30 +315,6 @@ def _get_custom_interpreter(implementation=None, version=None): return "{}{}".format(implementation, version) -def _generic_tags( - version=None, # type: Optional[str] - platform=None, # type: Optional[str] - impl=None, # type: Optional[str] - abi=None, # type: Optional[str] -): - # type: (...) -> Iterator[Tag] - interpreter = _get_custom_interpreter(impl, version) - - abis = None # type: Optional[List[str]] - if abi: - abis = [abi] - - platforms = None # type: Optional[List[str]] - if platform is not None: - platforms = _get_custom_platforms(platform, platform) - - return generic_tags( - interpreter=interpreter, - abis=abis, - platforms=platforms, - ) - - def _stable_unique_tags(tags): # type: (List[Tag]) -> Iterator[Tag] observed = set() # type: Set[Tag] @@ -393,7 +369,13 @@ def get_supported( ) ) else: - supported.extend(_generic_tags(version, platform, impl, abi)) + supported.extend( + generic_tags( + interpreter=interpreter, + abis=abis, + platforms=platforms, + ) + ) supported.extend( compatible_tags( python_version=python_version, From ad546b5e8da2b7758e7f795ff940071d82f0719e Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:54 -0500 Subject: [PATCH 27/34] Remove unnecessary conversion in get_supported Now that we're fully using packaging.tags, everything in the supported list is already Tag. Further, since each function is responsible for its own set of non-overlapping tags, we can also remove the de-duplication. --- src/pip/_internal/pep425tags.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 38ac99aa388..e577a295bdf 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -23,7 +23,7 @@ if MYPY_CHECK_RUNNING: from typing import ( - Callable, Iterator, List, Optional, Set, Tuple, Union + Callable, List, Optional, Tuple, Union ) from pip._vendor.packaging.tags import PythonVersion @@ -315,15 +315,6 @@ def _get_custom_interpreter(implementation=None, version=None): return "{}{}".format(implementation, version) -def _stable_unique_tags(tags): - # type: (List[Tag]) -> Iterator[Tag] - observed = set() # type: Set[Tag] - for tag in tags: - if tag not in observed: - observed.add(tag) - yield tag - - def get_supported( version=None, # type: Optional[str] platform=None, # type: Optional[str] @@ -343,7 +334,7 @@ def get_supported( :param abi: specify the exact abi you want valid tags for, or None. If None, use the local interpreter abi. """ - supported = [] # type: List[Union[Tag, Tuple[str, str, str]]] + supported = [] # type: List[Tag] python_version = None # type: Optional[PythonVersion] if version is not None: @@ -384,8 +375,4 @@ def get_supported( ) ) - tags = [ - parts if isinstance(parts, Tag) else Tag(*parts) - for parts in supported - ] - return list(_stable_unique_tags(tags)) + return supported From 9b3443583e73764411a0ad28f10934b4eca530c8 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:55 -0500 Subject: [PATCH 28/34] Simplify _get_custom_platforms Since we only call this function when platform is not None, we can drop one of the branches. This is the only place using our manylinux auto-deduction functions, so those can be removed next. --- src/pip/_internal/pep425tags.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index e577a295bdf..2d0664b952c 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -277,22 +277,13 @@ def _custom_manylinux_platforms(arch): return arches -def _get_custom_platforms(arch, platform): - # type: (str, Optional[str]) -> List[str] +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) - elif platform is None: - arches = [] - if is_manylinux2014_compatible(): - arches.append('manylinux2014' + arch_sep + arch_suffix) - if is_manylinux2010_compatible(): - arches.append('manylinux2010' + arch_sep + arch_suffix) - if is_manylinux1_compatible(): - arches.append('manylinux1' + arch_sep + arch_suffix) - arches.append(arch) else: arches = [arch] return arches @@ -348,7 +339,7 @@ def get_supported( platforms = None # type: Optional[List[str]] if platform is not None: - platforms = _get_custom_platforms(platform, platform) + platforms = _get_custom_platforms(platform) is_cpython = (impl or interpreter_name()) == "cp" if is_cpython: From 2455977bc86f1732024dfe19e2c72614f27327c9 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:57 -0500 Subject: [PATCH 29/34] Remove unused manylinux auto-deduction functions --- src/pip/_internal/pep425tags.py | 89 --------------------------------- tests/unit/test_pep425tags.py | 49 ------------------ 2 files changed, 138 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 2d0664b952c..15b195d1688 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -18,7 +18,6 @@ mac_platforms, ) -import pip._internal.utils.glibc from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: @@ -136,94 +135,6 @@ def get_platform(): return result -def is_linux_armhf(): - # type: () -> bool - if get_platform() != "linux_armv7l": - return False - # hard-float ABI can be detected from the ELF header of the running - # process - try: - with open(sys.executable, 'rb') as f: - elf_header_raw = f.read(40) # read 40 first bytes of ELF header - except (IOError, OSError, TypeError): - return False - if elf_header_raw is None or len(elf_header_raw) < 40: - return False - if isinstance(elf_header_raw, str): - elf_header = [ord(c) for c in elf_header_raw] - else: - elf_header = [b for b in elf_header_raw] - result = elf_header[0:4] == [0x7f, 0x45, 0x4c, 0x46] # ELF magic number - result &= elf_header[4:5] == [1] # 32-bit ELF - result &= elf_header[5:6] == [1] # little-endian - result &= elf_header[18:20] == [0x28, 0] # ARM machine - result &= elf_header[39:40] == [5] # ARM EABIv5 - result &= (elf_header[37:38][0] & 4) == 4 # EF_ARM_ABI_FLOAT_HARD - return result - - -def is_manylinux1_compatible(): - # type: () -> bool - # Only Linux, and only x86-64 / i686 - if get_platform() not in {"linux_x86_64", "linux_i686"}: - return False - - # Check for presence of _manylinux module - try: - import _manylinux - return bool(_manylinux.manylinux1_compatible) - except (ImportError, AttributeError): - # Fall through to heuristic check below - pass - - # Check glibc version. CentOS 5 uses glibc 2.5. - return pip._internal.utils.glibc.have_compatible_glibc(2, 5) - - -def is_manylinux2010_compatible(): - # type: () -> bool - # Only Linux, and only x86-64 / i686 - if get_platform() not in {"linux_x86_64", "linux_i686"}: - return False - - # Check for presence of _manylinux module - try: - import _manylinux - return bool(_manylinux.manylinux2010_compatible) - except (ImportError, AttributeError): - # Fall through to heuristic check below - pass - - # Check glibc version. CentOS 6 uses glibc 2.12. - return pip._internal.utils.glibc.have_compatible_glibc(2, 12) - - -def is_manylinux2014_compatible(): - # type: () -> bool - # Only Linux, and only supported architectures - platform = get_platform() - if platform not in {"linux_x86_64", "linux_i686", "linux_aarch64", - "linux_armv7l", "linux_ppc64", "linux_ppc64le", - "linux_s390x"}: - return False - - # check for hard-float ABI in case we're running linux_armv7l not to - # install hard-float ABI wheel in a soft-float ABI environment - if platform == "linux_armv7l" and not is_linux_armhf(): - return False - - # Check for presence of _manylinux module - try: - import _manylinux - return bool(_manylinux.manylinux2014_compatible) - except (ImportError, AttributeError): - # Fall through to heuristic check below - pass - - # Check glibc version. CentOS 7 uses glibc 2.17. - return pip._internal.utils.glibc.have_compatible_glibc(2, 17) - - def get_all_minor_versions_as_strings(version_info): # type: (Tuple[int, ...]) -> List[str] versions = [] diff --git a/tests/unit/test_pep425tags.py b/tests/unit/test_pep425tags.py index a5469725e96..14774d530cf 100644 --- a/tests/unit/test_pep425tags.py +++ b/tests/unit/test_pep425tags.py @@ -119,55 +119,6 @@ def test_manual_abi_dm_flags(self): self.abi_tag_unicode('dm', {'Py_DEBUG': True, 'WITH_PYMALLOC': True}) -@pytest.mark.parametrize('is_manylinux_compatible', [ - pep425tags.is_manylinux1_compatible, - pep425tags.is_manylinux2010_compatible, - pep425tags.is_manylinux2014_compatible, -]) -class TestManylinuxTags(object): - """ - Tests common to all manylinux tags (e.g. manylinux1, manylinux2010, - ...) - """ - @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: True) - def test_manylinux_compatible_on_linux_x86_64(self, - is_manylinux_compatible): - """ - Test that manylinuxes are enabled on linux_x86_64 - """ - assert is_manylinux_compatible() - - @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_i686') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: True) - def test_manylinux_compatible_on_linux_i686(self, - is_manylinux_compatible): - """ - Test that manylinuxes are enabled on linux_i686 - """ - assert is_manylinux_compatible() - - @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: False) - def test_manylinux_2(self, is_manylinux_compatible): - """ - Test that manylinuxes are disabled with incompatible glibc - """ - assert not is_manylinux_compatible() - - @patch('pip._internal.pep425tags.get_platform', lambda: 'arm6vl') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: True) - def test_manylinux_3(self, is_manylinux_compatible): - """ - Test that manylinuxes are disabled on arm6vl - """ - assert not is_manylinux_compatible() - - class TestManylinux2010Tags(object): @pytest.mark.parametrize("manylinux2010,manylinux1", [ From 7aaa705c15b16b13ac64807d1d23dcd797f5977d Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:58 -0500 Subject: [PATCH 30/34] Remove unused glibc functions The remaining glibc-related functions are required to allow us to put the libc version in the pip user agent (for stats). --- src/pip/_internal/utils/glibc.py | 28 -------------------------- tests/unit/test_utils.py | 34 -------------------------------- 2 files changed, 62 deletions(-) diff --git a/src/pip/_internal/utils/glibc.py b/src/pip/_internal/utils/glibc.py index 42b1d3919a3..36104244138 100644 --- a/src/pip/_internal/utils/glibc.py +++ b/src/pip/_internal/utils/glibc.py @@ -4,9 +4,7 @@ from __future__ import absolute_import import os -import re import sys -import warnings from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -69,32 +67,6 @@ def glibc_version_string_ctypes(): return version_str -# Separated out from have_compatible_glibc for easier unit testing -def check_glibc_version(version_str, required_major, minimum_minor): - # type: (str, int, int) -> bool - # Parse string and check against requested version. - # - # We use a regexp instead of str.split because we want to discard any - # random junk that might come after the minor version -- this might happen - # in patched/forked versions of glibc (e.g. Linaro's version of glibc - # uses version strings like "2.20-2014.11"). See gh-3588. - m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) - if not m: - warnings.warn("Expected glibc version with 2 components major.minor," - " got: %s" % version_str, RuntimeWarning) - return False - return (int(m.group("major")) == required_major and - int(m.group("minor")) >= minimum_minor) - - -def have_compatible_glibc(required_major, minimum_minor): - # type: (int, int) -> bool - version_str = glibc_version_string() - if version_str is None: - return False - return check_glibc_version(version_str, required_major, minimum_minor) - - # platform.libc_ver regularly returns completely nonsensical glibc # versions. E.g. on my computer, platform says: # diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 64c8aabf505..011543bdcc5 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -10,7 +10,6 @@ import stat import sys import time -import warnings from io import BytesIO import pytest @@ -24,7 +23,6 @@ from pip._internal.utils.deprecation import PipDeprecationWarning, deprecated from pip._internal.utils.encoding import BOMS, auto_decode from pip._internal.utils.glibc import ( - check_glibc_version, glibc_version_string, glibc_version_string_confstr, glibc_version_string_ctypes, @@ -538,38 +536,6 @@ def raises(error): class TestGlibc(object): - def test_manylinux_check_glibc_version(self): - """ - Test that the check_glibc_version function is robust against weird - glibc version strings. - """ - for two_twenty in ["2.20", - # used by "linaro glibc", see gh-3588 - "2.20-2014.11", - # weird possibilities that I just made up - "2.20+dev", - "2.20-custom", - "2.20.1", - ]: - assert check_glibc_version(two_twenty, 2, 15) - assert check_glibc_version(two_twenty, 2, 20) - assert not check_glibc_version(two_twenty, 2, 21) - assert not check_glibc_version(two_twenty, 3, 15) - assert not check_glibc_version(two_twenty, 1, 15) - - # For strings that we just can't parse at all, we should warn and - # return false - for bad_string in ["asdf", "", "foo.bar"]: - with warnings.catch_warnings(record=True) as ws: - warnings.filterwarnings("always") - assert not check_glibc_version(bad_string, 2, 5) - for w in ws: - if "Expected glibc version with" in str(w.message): - break - else: - # Didn't find the warning we were expecting - assert False - @pytest.mark.skipif("sys.platform == 'win32'") def test_glibc_version_string(self, monkeypatch): monkeypatch.setattr( From 896317d13d9bccf75b9cb35a37a83d93d3d2e55b Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:59 -0500 Subject: [PATCH 31/34] Remove unused abi functions Previously, these were used when the user did not provide an explicit ABI. Now this is handled internally in `packaging.tags` (by `_cpython_abi` and `_generic_abi`). --- src/pip/_internal/pep425tags.py | 56 +------------------------ tests/unit/test_pep425tags.py | 73 ++------------------------------- 2 files changed, 4 insertions(+), 125 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 15b195d1688..915c92b81d6 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -6,7 +6,6 @@ import platform import re import sys -import sysconfig from pip._vendor.packaging.tags import ( Tag, @@ -21,9 +20,7 @@ from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: - from typing import ( - Callable, List, Optional, Tuple, Union - ) + from typing import List, Optional, Tuple from pip._vendor.packaging.tags import PythonVersion @@ -32,11 +29,6 @@ _osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') -def get_config_var(var): - # type: (str) -> Optional[str] - return sysconfig.get_config_var(var) - - def version_info_to_nodot(version_info): # type: (Tuple[int, ...]) -> str # Only use up to the first two numbers. @@ -57,52 +49,6 @@ def get_impl_version_info(): return sys.version_info[0], sys.version_info[1] -def get_flag(var, fallback, expected=True, warn=True): - # type: (str, Callable[..., bool], Union[bool, int], bool) -> bool - """Use a fallback method for determining SOABI flags if the needed config - var is unset or unavailable.""" - val = get_config_var(var) - if val is None: - if warn: - logger.debug("Config variable '%s' is unset, Python ABI tag may " - "be incorrect", var) - return fallback() - return val == expected - - -def get_abi_tag(): - # type: () -> Optional[str] - """Return the ABI tag based on SOABI (if available) or emulate SOABI - (CPython 2, PyPy).""" - soabi = get_config_var('SOABI') - impl = interpreter_name() - abi = None # type: Optional[str] - - if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'): - d = '' - m = '' - u = '' - is_cpython = (impl == 'cp') - if get_flag( - 'Py_DEBUG', lambda: hasattr(sys, 'gettotalrefcount'), - warn=is_cpython): - d = 'd' - if sys.version_info < (3, 8) and get_flag( - 'WITH_PYMALLOC', lambda: is_cpython, warn=is_cpython): - m = 'm' - if sys.version_info < (3, 3) and get_flag( - 'Py_UNICODE_SIZE', lambda: sys.maxunicode == 0x10ffff, - expected=4, warn=is_cpython): - u = 'u' - abi = '%s%s%s%s%s' % (impl, interpreter_version(), d, m, u) - elif soabi and soabi.startswith('cpython-'): - abi = 'cp' + soabi.split('-')[1] - elif soabi: - abi = soabi.replace('.', '_').replace('-', '_') - - return abi - - def _is_running_32bit(): # type: () -> bool return sys.maxsize == 2147483647 diff --git a/tests/unit/test_pep425tags.py b/tests/unit/test_pep425tags.py index 14774d530cf..71d0aefe4f9 100644 --- a/tests/unit/test_pep425tags.py +++ b/tests/unit/test_pep425tags.py @@ -1,8 +1,7 @@ -import sys +import sysconfig import pytest from mock import patch -from pip._vendor.packaging.tags import interpreter_name, interpreter_version from pip._internal import pep425tags @@ -28,9 +27,7 @@ def mock_get_config_var(self, **kwd): """ Patch sysconfig.get_config_var for arbitrary keys. """ - import pip._internal.pep425tags - - get_config_var = pip._internal.pep425tags.sysconfig.get_config_var + get_config_var = sysconfig.get_config_var def _mock_get_config_var(var): if var in kwd: @@ -38,45 +35,6 @@ def _mock_get_config_var(var): return get_config_var(var) return _mock_get_config_var - def abi_tag_unicode(self, flags, config_vars): - """ - Used to test ABI tags, verify correct use of the `u` flag - """ - import pip._internal.pep425tags - - config_vars.update({'SOABI': None}) - base = interpreter_name() + interpreter_version() - - if sys.version_info >= (3, 8): - # Python 3.8 removes the m flag, so don't look for it. - flags = flags.replace('m', '') - - if sys.version_info < (3, 3): - config_vars.update({'Py_UNICODE_SIZE': 2}) - mock_gcf = self.mock_get_config_var(**config_vars) - with patch('pip._internal.pep425tags.sysconfig.get_config_var', - mock_gcf): - abi_tag = pip._internal.pep425tags.get_abi_tag() - assert abi_tag == base + flags - - config_vars.update({'Py_UNICODE_SIZE': 4}) - mock_gcf = self.mock_get_config_var(**config_vars) - with patch('pip._internal.pep425tags.sysconfig.get_config_var', - mock_gcf): - abi_tag = pip._internal.pep425tags.get_abi_tag() - assert abi_tag == base + flags + 'u' - - else: - # On Python >= 3.3, UCS-4 is essentially permanently enabled, and - # Py_UNICODE_SIZE is None. SOABI on these builds does not include - # the 'u' so manual SOABI detection should not do so either. - config_vars.update({'Py_UNICODE_SIZE': None}) - mock_gcf = self.mock_get_config_var(**config_vars) - with patch('pip._internal.pep425tags.sysconfig.get_config_var', - mock_gcf): - abi_tag = pip._internal.pep425tags.get_abi_tag() - assert abi_tag == base + flags - def test_no_hyphen_tag(self): """ Test that no tag contains a hyphen. @@ -85,8 +43,7 @@ def test_no_hyphen_tag(self): mock_gcf = self.mock_get_config_var(SOABI='cpython-35m-darwin') - with patch('pip._internal.pep425tags.sysconfig.get_config_var', - mock_gcf): + with patch('sysconfig.get_config_var', mock_gcf): supported = pip._internal.pep425tags.get_supported() for tag in supported: @@ -94,30 +51,6 @@ def test_no_hyphen_tag(self): assert '-' not in tag.abi assert '-' not in tag.platform - def test_manual_abi_noflags(self): - """ - Test that no flags are set on a non-PyDebug, non-Pymalloc ABI tag. - """ - self.abi_tag_unicode('', {'Py_DEBUG': False, 'WITH_PYMALLOC': False}) - - def test_manual_abi_d_flag(self): - """ - Test that the `d` flag is set on a PyDebug, non-Pymalloc ABI tag. - """ - self.abi_tag_unicode('d', {'Py_DEBUG': True, 'WITH_PYMALLOC': False}) - - def test_manual_abi_m_flag(self): - """ - Test that the `m` flag is set on a non-PyDebug, Pymalloc ABI tag. - """ - self.abi_tag_unicode('m', {'Py_DEBUG': False, 'WITH_PYMALLOC': True}) - - def test_manual_abi_dm_flags(self): - """ - Test that the `dm` flags are set on a PyDebug, Pymalloc ABI tag. - """ - self.abi_tag_unicode('dm', {'Py_DEBUG': True, 'WITH_PYMALLOC': True}) - class TestManylinux2010Tags(object): From 2b1b60f6db39ee3f26a0174ae66fbb909f94a709 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:03:00 -0500 Subject: [PATCH 32/34] Remove unused get_platform function Now handled internally in `packaging.tags` (in `_platform_tags`). --- src/pip/_internal/pep425tags.py | 34 --------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 915c92b81d6..3e5bc234b55 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -1,9 +1,7 @@ """Generate and work with PEP 425 Compatibility Tags.""" from __future__ import absolute_import -import distutils.util import logging -import platform import re import sys @@ -49,38 +47,6 @@ def get_impl_version_info(): return sys.version_info[0], sys.version_info[1] -def _is_running_32bit(): - # type: () -> bool - return sys.maxsize == 2147483647 - - -def get_platform(): - # type: () -> str - """Return our platform name 'win32', 'linux_x86_64'""" - if sys.platform == 'darwin': - # distutils.util.get_platform() returns the release based on the value - # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may - # be significantly older than the user's current machine. - release, _, machine = platform.mac_ver() - split_ver = release.split('.') - - if machine == "x86_64" and _is_running_32bit(): - machine = "i386" - elif machine == "ppc64" and _is_running_32bit(): - machine = "ppc" - - return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine) - - # XXX remove distutils dependency - result = distutils.util.get_platform().replace('.', '_').replace('-', '_') - if result == "linux_x86_64" and _is_running_32bit(): - # 32 bit Python program (running on a 64 bit Linux): pip should only - # install and run 32 bit compiled extensions in that case. - result = "linux_i686" - - return result - - def get_all_minor_versions_as_strings(version_info): # type: (Tuple[int, ...]) -> List[str] versions = [] From ae21af701db314a6ff97c86b6f3afb96d10c8fd4 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:02:59 -0500 Subject: [PATCH 33/34] Remove unused version functions --- src/pip/_internal/pep425tags.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 3e5bc234b55..a2386ee75b8 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -3,7 +3,6 @@ import logging import re -import sys from pip._vendor.packaging.tags import ( Tag, @@ -33,30 +32,6 @@ def version_info_to_nodot(version_info): return ''.join(map(str, version_info[:2])) -def get_impl_version_info(): - # type: () -> Tuple[int, ...] - """Return sys.version_info-like tuple for use in decrementing the minor - version.""" - if interpreter_name() == 'pp': - # as per https://github.com/pypa/pip/issues/2882 - # attrs exist only on pypy - return (sys.version_info[0], - sys.pypy_version_info.major, # type: ignore - sys.pypy_version_info.minor) # type: ignore - else: - return sys.version_info[0], sys.version_info[1] - - -def get_all_minor_versions_as_strings(version_info): - # type: (Tuple[int, ...]) -> List[str] - versions = [] - major = version_info[:-1] - # Support all previous minor Python versions. - for minor in range(version_info[-1], -1, -1): - versions.append(''.join(map(str, major + (minor,)))) - return versions - - def _mac_platforms(arch): # type: (str) -> List[str] match = _osx_arch_pat.match(arch) From d7fda717ac1e269806607d912d126c047348aed0 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Sat, 23 Nov 2019 18:03:01 -0500 Subject: [PATCH 34/34] Add news --- news/6908.removal | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 news/6908.removal diff --git a/news/6908.removal b/news/6908.removal new file mode 100644 index 00000000000..aca9d590ab0 --- /dev/null +++ b/news/6908.removal @@ -0,0 +1,2 @@ +Remove wheel tag calculation from pip and use ``packaging.tags``. This +should provide more tags ordered better than in prior releases.