From 372650d51d251581b9b30923c0bec26a6e514359 Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 8 Apr 2020 16:18:39 +0300 Subject: [PATCH] Support PEP 600 tags --- packaging/tags.py | 46 ++++++++++++++++++++++++++++++++++++++++------ tests/test_tags.py | 2 ++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/packaging/tags.py b/packaging/tags.py index 25d8e0080..b656fedfe 100644 --- a/packaging/tags.py +++ b/packaging/tags.py @@ -496,7 +496,14 @@ def _glibc_version_string_ctypes(): # 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. + # Check against requested version. + major, minor = _parse_glibc_version(version_str) + return major == required_major and minor >= minimum_minor + + +def _parse_glibc_version(version_str): + # type: (str) -> Tuple[int, int] + # Parse glibc 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 @@ -509,11 +516,8 @@ def _check_glibc_version(version_str, required_major, minimum_minor): " got: %s" % version_str, RuntimeWarning, ) - return False - return ( - int(m.group("major")) == required_major - and int(m.group("minor")) >= minimum_minor - ) + return (-1, -1) + return (int(m.group("major")), int(m.group("minor"))) def _have_compatible_glibc(required_major, minimum_minor): @@ -524,6 +528,14 @@ def _have_compatible_glibc(required_major, minimum_minor): return _check_glibc_version(version_str, required_major, minimum_minor) +def _get_glibc_version(): + # type: () -> Tuple[int, int] + version_str = _glibc_version_string() + if version_str is None: + return -1, -1 + return _parse_glibc_version(version_str) + + # Python does not provide platform information at sufficient granularity to # identify the architecture of the running executable in some cases, so we # determine it dynamically by reading the information from the running @@ -652,11 +664,30 @@ def _linux_platforms(is_32bit=_32_BIT_INTERPRETER): linux = "linux_armv7l" manylinux_support = [] _, arch = linux.split("_", 1) + pep600_support = [] if _have_compatible_manylinux_abi(arch): if arch in {"x86_64", "i686", "aarch64", "armv7l", "ppc64", "ppc64le", "s390x"}: manylinux_support.append( ("manylinux2014", (2, 17)) ) # CentOS 7 w/ glibc 2.17 (PEP 599) + if arch in ("x86_64", "i686"): + # glibc in manylinux1 is 2.5 + min_minor = 5 + else: + # glibc in manylinux2014 is 2.5 + min_minor = 17 + cur_glibc = _get_glibc_version() + for glibc_minor in range(min_minor, cur_glibc[1]): + if _have_compatible_glibc(2, glibc_minor): + pep600_support.append( + ( + "manylinux_2_{}_{}".format(glibc_minor, arch), + (2, glibc_minor), + ) + ) + else: + # no need to keep incrementing + break if arch in {"x86_64", "i686"}: manylinux_support.append( ("manylinux2010", (2, 12)) @@ -672,6 +703,9 @@ def _linux_platforms(is_32bit=_32_BIT_INTERPRETER): # Support for a later manylinux implies support for an earlier version. for name, _ in manylinux_support_iter: yield linux.replace("linux", name) + for name, glibc_verison in iter(pep600_support): + if _is_manylinux_compatible(name, glibc_version): + yield name yield linux diff --git a/tests/test_tags.py b/tests/test_tags.py index 4840e196d..b4fd8e212 100644 --- a/tests/test_tags.py +++ b/tests/test_tags.py @@ -484,6 +484,7 @@ def test_linux_platforms_manylinux2014(self, is_x86, monkeypatch): assert platforms == expected def test_linux_platforms_manylinux2014_armhf_abi(self, monkeypatch): + monkeypatch.setattr(tags, "_glibc_version_string", lambda: "2.30") monkeypatch.setattr( tags, "_is_manylinux_compatible", lambda name, _: name == "manylinux2014" ) @@ -498,6 +499,7 @@ def test_linux_platforms_manylinux2014_armhf_abi(self, monkeypatch): assert platforms == expected def test_linux_platforms_manylinux2014_i386_abi(self, monkeypatch): + monkeypatch.setattr(tags, "_glibc_version_string", lambda: "2.20") monkeypatch.setattr( tags, "_is_manylinux_compatible", lambda name, _: name == "manylinux2014" )