]>
crepu.dev Git - config.git/blob - djavu-asus/elpy/rpc-venv/lib/python3.11/site-packages/packaging/_musllinux.py
3 This module implements logic to detect if the currently running Python is
4 linked against musl, and what musl version is used.
11 from typing
import Iterator
, NamedTuple
, Optional
, Sequence
13 from ._elffile
import ELFFile
16 class _MuslVersion(NamedTuple
):
21 def _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":
25 m
= re
.match(r
"Version (\d+)\.(\d+)", lines
[1])
28 return _MuslVersion(major
=int(m
.group(1)), minor
=int(m
.group(2)))
31 @functools.lru_cache()
32 def _get_musl_version(executable
: str) -> Optional
[_MuslVersion
]:
33 """Detect currently-running musl runtime version.
35 This is done by checking the specified executable's dynamic linking
36 information, and invoking the loader to parse its output for a version
37 string. If the loader is musl, the output would be something like::
41 Dynamic Program Loader
44 with
open(executable
, "rb") as f
:
45 ld
= ELFFile(f
).interpreter
46 except (OSError, TypeError, ValueError):
48 if ld
is None or "musl" not in ld
:
50 proc
= subprocess
.run([ld
], stderr
=subprocess
.PIPE
, text
=True)
51 return _parse_musl_version(proc
.stderr
)
54 def platform_tags(archs
: Sequence
[str]) -> Iterator
[str]:
55 """Generate musllinux tags compatible to the current platform.
57 :param archs: Sequence of compatible architectures.
58 The first one shall be the closest to the actual architecture and be the part of
59 platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
60 The ``linux_`` prefix is assumed as a prerequisite for the current platform to
61 be musllinux-compatible.
63 :returns: An iterator of compatible musllinux tags.
65 sys_musl
= _get_musl_version(sys
.executable
)
66 if sys_musl
is None: # Python not dynamically linked against musl.
69 for minor
in range(sys_musl
.minor
, -1, -1):
70 yield f
"musllinux_{sys_musl.major}_{minor}_{arch}"
73 if __name__
== "__main__": # pragma: no cover
76 plat
= sysconfig
.get_platform()
77 assert plat
.startswith("linux-"), "not linux"
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])):