Skip to content

Commit

Permalink
fix: circular dependency
Browse files Browse the repository at this point in the history
move Platform definition to libc.py and also rename it Libc
  • Loading branch information
mayeut committed Aug 1, 2021
1 parent f4c195f commit 0a00272
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 42 deletions.
2 changes: 1 addition & 1 deletion auditwheel/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ class AuditwheelException(Exception):
pass


class InvalidPlatform(AuditwheelException):
class InvalidLibc(AuditwheelException):
pass
6 changes: 3 additions & 3 deletions auditwheel/lddtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)
Expand Down Expand Up @@ -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"))
Expand Down
23 changes: 23 additions & 0 deletions auditwheel/libc.py
Original file line number Diff line number Diff line change
@@ -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
10 changes: 5 additions & 5 deletions auditwheel/musllinux.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import re
from typing import NamedTuple

from auditwheel.error import InvalidPlatform
from auditwheel.error import InvalidLibc

LOG = logging.getLogger(__name__)

Expand All @@ -20,15 +20,15 @@ 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<platform>\w+)\.so.1 " # TODO drop the platform
r"=> (?P<path>[/\-\w.]+)",
ldd)

if not match:
raise InvalidPlatform
raise InvalidLibc

return pathlib.Path(match.group("path"))

Expand All @@ -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 "
Expand All @@ -52,7 +52,7 @@ def get_musl_version(ld_path: pathlib.Path) -> MuslVersion:
r"(?P<patch>\d+)",
ld)
if not match:
raise InvalidPlatform
raise InvalidLibc

return MuslVersion(
int(match.group("major")),
Expand Down
36 changes: 9 additions & 27 deletions auditwheel/policy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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:
Expand Down Expand Up @@ -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}'
Expand All @@ -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": {
Expand All @@ -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)
Expand All @@ -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)
Expand Down
12 changes: 6 additions & 6 deletions tests/unit/test_musllinux.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")


Expand Down

0 comments on commit 0a00272

Please sign in to comment.