Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
_musllinux.py84 linesDownload Raw Back to packaging
1"""PEP 656 support.2 3This module implements logic to detect if the currently running Python is4linked against musl, and what musl version is used.5"""6 7import functools8import re9import subprocess10import sys11from typing import Iterator, NamedTuple, Optional, Sequence12 13from ._elffile import ELFFile14 15 16class _MuslVersion(NamedTuple):17    major: int18    minor: int19 20 21def _parse_musl_version(output: str) -> Optional[_MuslVersion]:22    lines = [n for n in (n.strip() for n in output.splitlines()) if n]23    if len(lines) < 2 or lines[0][:4] != "musl":24        return None25    m = re.match(r"Version (\d+)\.(\d+)", lines[1])26    if not m:27        return None28    return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2)))29 30 31@functools.lru_cache()32def _get_musl_version(executable: str) -> Optional[_MuslVersion]:33    """Detect currently-running musl runtime version.34 35    This is done by checking the specified executable's dynamic linking36    information, and invoking the loader to parse its output for a version37    string. If the loader is musl, the output would be something like::38 39        musl libc (x86_64)40        Version 1.2.241        Dynamic Program Loader42    """43    try:44        with open(executable, "rb") as f:45            ld = ELFFile(f).interpreter46    except (OSError, TypeError, ValueError):47        return None48    if ld is None or "musl" not in ld:49        return None50    proc = subprocess.run([ld], stderr=subprocess.PIPE, text=True)51    return _parse_musl_version(proc.stderr)52 53 54def platform_tags(archs: Sequence[str]) -> Iterator[str]:55    """Generate musllinux tags compatible to the current platform.56 57    :param archs: Sequence of compatible architectures.58        The first one shall be the closest to the actual architecture and be the part of59        platform tag after the ``linux_`` prefix, e.g. ``x86_64``.60        The ``linux_`` prefix is assumed as a prerequisite for the current platform to61        be musllinux-compatible.62 63    :returns: An iterator of compatible musllinux tags.64    """65    sys_musl = _get_musl_version(sys.executable)66    if sys_musl is None:  # Python not dynamically linked against musl.67        return68    for arch in archs:69        for minor in range(sys_musl.minor, -1, -1):70            yield f"musllinux_{sys_musl.major}_{minor}_{arch}"71 72 73if __name__ == "__main__":  # pragma: no cover74    import sysconfig75 76    plat = sysconfig.get_platform()77    assert plat.startswith("linux-"), "not linux"78 79    print("plat:", plat)80    print("musl:", _get_musl_version(sys.executable))81    print("tags:", end=" ")82    for t in platform_tags(re.sub(r"[.-]", "_", plat.split("-", 1)[-1])):83        print(t, end="\n      ")84 
codekingpro/portable-devtools · Team Ai