From 0a00272b02fe1702f5143758814e6a9dec0a71e8 Mon Sep 17 00:00:00 2001 From: mayeut Date: Sat, 31 Jul 2021 19:40:42 +0200 Subject: [PATCH] fix: circular dependency move Platform definition to libc.py and also rename it Libc --- auditwheel/error.py | 2 +- auditwheel/lddtree.py | 6 +++--- auditwheel/libc.py | 23 ++++++++++++++++++++++ auditwheel/musllinux.py | 10 +++++----- auditwheel/policy/__init__.py | 36 +++++++++-------------------------- tests/unit/test_musllinux.py | 12 ++++++------ 6 files changed, 47 insertions(+), 42 deletions(-) create mode 100644 auditwheel/libc.py diff --git a/auditwheel/error.py b/auditwheel/error.py index 52887b2c..c95348c8 100644 --- a/auditwheel/error.py +++ b/auditwheel/error.py @@ -2,5 +2,5 @@ class AuditwheelException(Exception): pass -class InvalidPlatform(AuditwheelException): +class InvalidLibc(AuditwheelException): pass diff --git a/auditwheel/lddtree.py b/auditwheel/lddtree.py index 254e499d..ab9098dd 100644 --- a/auditwheel/lddtree.py +++ b/auditwheel/lddtree.py @@ -21,7 +21,7 @@ from typing import List, Dict, Optional, Any, Tuple from elftools.elf.elffile import ELFFile -from .policy import get_policy_platform, Platform +from .libc import get_libc, Libc log = logging.getLogger(__name__) @@ -198,8 +198,8 @@ def load_ld_paths(root: str = '/', prefix: str = '') -> Dict[str, List[str]]: # on a per-ELF basis so it can get turned into the right thing. ldpaths['env'] = parse_ld_paths(env_ldpath, path='') - policy_platform = get_policy_platform() - if policy_platform == Platform.MUSLLINUX: + libc = get_libc() + if libc == Libc.MUSL: # from https://git.musl-libc.org/cgit/musl/tree/ldso # /dynlink.c?id=3f701faace7addc75d16dea8a6cd769fa5b3f260#n1063 ld_musl = list(Path(root + prefix + '/etc').glob("ld-musl-*.path")) diff --git a/auditwheel/libc.py b/auditwheel/libc.py new file mode 100644 index 00000000..5ff9ca48 --- /dev/null +++ b/auditwheel/libc.py @@ -0,0 +1,23 @@ +import logging +from enum import IntEnum + +from .error import InvalidLibc +from .musllinux import find_musl_libc + + +logger = logging.getLogger(__name__) + + +class Libc(IntEnum): + GLIBC = 1, + MUSL = 2, + + +def get_libc() -> Libc: + try: + find_musl_libc() + logger.debug("Detected musl libc") + return Libc.MUSL + except InvalidLibc: + logger.debug("Falling back to GNU libc") + return Libc.GLIBC diff --git a/auditwheel/musllinux.py b/auditwheel/musllinux.py index b352a4d8..32f6ef27 100644 --- a/auditwheel/musllinux.py +++ b/auditwheel/musllinux.py @@ -4,7 +4,7 @@ import re from typing import NamedTuple -from auditwheel.error import InvalidPlatform +from auditwheel.error import InvalidLibc LOG = logging.getLogger(__name__) @@ -20,7 +20,7 @@ def find_musl_libc() -> pathlib.Path: ldd = subprocess.check_output(["ldd", "/bin/ls"], errors='strict') except (subprocess.CalledProcessError, FileNotFoundError): LOG.error("Failed to determine libc version", exc_info=True) - raise InvalidPlatform + raise InvalidLibc match = re.search( r"libc\.musl-(?P\w+)\.so.1 " # TODO drop the platform @@ -28,7 +28,7 @@ def find_musl_libc() -> pathlib.Path: ldd) if not match: - raise InvalidPlatform + raise InvalidLibc return pathlib.Path(match.group("path")) @@ -43,7 +43,7 @@ def get_musl_version(ld_path: pathlib.Path) -> MuslVersion: ).stderr except FileNotFoundError: LOG.error("Failed to determine musl version", exc_info=True) - raise InvalidPlatform + raise InvalidLibc match = re.search( r"Version " @@ -52,7 +52,7 @@ def get_musl_version(ld_path: pathlib.Path) -> MuslVersion: r"(?P\d+)", ld) if not match: - raise InvalidPlatform + raise InvalidLibc return MuslVersion( int(match.group("major")), diff --git a/auditwheel/policy/__init__.py b/auditwheel/policy/__init__.py index 264104ca..99556818 100644 --- a/auditwheel/policy/__init__.py +++ b/auditwheel/policy/__init__.py @@ -2,25 +2,19 @@ import json import platform as _platform_module from collections import defaultdict -from enum import IntEnum from pathlib import Path from typing import Dict, List, Optional, Set from os.path import join, dirname, abspath import logging -from ..error import InvalidPlatform +from ..libc import get_libc, Libc from ..musllinux import find_musl_libc, get_musl_version + _HERE = Path(__file__).parent logger = logging.getLogger(__name__) - -class Platform(IntEnum): - MANYLINUX = 1, - MUSLLINUX = 2 - - # https://docs.python.org/3/library/platform.html#platform.architecture bits = 8 * (8 if sys.maxsize > 2 ** 32 else 4) @@ -34,19 +28,7 @@ def get_arch_name() -> str: _ARCH_NAME = get_arch_name() - - -def get_policy_platform() -> Platform: - try: - find_musl_libc() - logger.debug("Detected musl libc") - return Platform.MUSLLINUX - except InvalidPlatform: - logger.debug("Falling back to GNU libc") - return Platform.MANYLINUX - - -_PLATFORM = get_policy_platform() +_LIBC = get_libc() def _validate_pep600_compliance(policies) -> None: @@ -82,13 +64,13 @@ def _validate_pep600_compliance(policies) -> None: _POLICY_JSON_MAP = { - Platform.MANYLINUX: _HERE / 'manylinux-policy.json', - Platform.MUSLLINUX: _HERE / 'musllinux-policy.json', + Libc.GLIBC: _HERE / 'manylinux-policy.json', + Libc.MUSL: _HERE / 'musllinux-policy.json', } def _get_musl_policy(): - if _PLATFORM != Platform.MUSLLINUX: + if _LIBC != Libc.MUSL: return None musl_version = get_musl_version(find_musl_libc()) return f'musllinux_{musl_version.major}_{musl_version.minor}' @@ -98,7 +80,7 @@ def _get_musl_policy(): def _fixup_musl_libc_soname(whitelist): - if _PLATFORM != Platform.MUSLLINUX: + if _LIBC != Libc.MUSL: return whitelist soname_map = { "libc.so": { @@ -121,7 +103,7 @@ def _fixup_musl_libc_soname(whitelist): return new_whitelist -with _POLICY_JSON_MAP[_PLATFORM].open() as f: +with _POLICY_JSON_MAP[_LIBC].open() as f: _POLICIES = [] _policies_temp = json.load(f) _validate_pep600_compliance(_policies_temp) @@ -137,7 +119,7 @@ def _fixup_musl_libc_soname(whitelist): for alias in _p['aliases']] _p['lib_whitelist'] = _fixup_musl_libc_soname(_p['lib_whitelist']) _POLICIES.append(_p) - if _PLATFORM == Platform.MUSLLINUX: + if _LIBC == Libc.MUSL: assert len(_POLICIES) == 2, _POLICIES POLICY_PRIORITY_HIGHEST = max(p['priority'] for p in _POLICIES) diff --git a/tests/unit/test_musllinux.py b/tests/unit/test_musllinux.py index 4dfebe10..4e56180c 100644 --- a/tests/unit/test_musllinux.py +++ b/tests/unit/test_musllinux.py @@ -4,39 +4,39 @@ import pytest from auditwheel.musllinux import find_musl_libc, get_musl_version -from auditwheel.error import InvalidPlatform +from auditwheel.error import InvalidLibc @patch("auditwheel.musllinux.subprocess.check_output") def test_find_musllinux_no_ldd(check_output_mock): check_output_mock.side_effect = FileNotFoundError() - with pytest.raises(InvalidPlatform): + with pytest.raises(InvalidLibc): find_musl_libc() @patch("auditwheel.musllinux.subprocess.check_output") def test_find_musllinux_ldd_error(check_output_mock): check_output_mock.side_effect = subprocess.CalledProcessError(1, "ldd") - with pytest.raises(InvalidPlatform): + with pytest.raises(InvalidLibc): find_musl_libc() @patch("auditwheel.musllinux.subprocess.check_output") def test_find_musllinux_not_found(check_output_mock): check_output_mock.return_value = "" - with pytest.raises(InvalidPlatform): + with pytest.raises(InvalidLibc): find_musl_libc() def test_get_musl_version_invalid_path(): - with pytest.raises(InvalidPlatform): + with pytest.raises(InvalidLibc): get_musl_version("/tmp/no/executable/here") @patch("auditwheel.musllinux.subprocess.run") def test_get_musl_version_invalid_version(run_mock): run_mock.return_value = subprocess.CompletedProcess([], 1, None, "Version 1.1") - with pytest.raises(InvalidPlatform): + with pytest.raises(InvalidLibc): get_musl_version("anything")