o {ۓa @s~dZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z m Z m Z m Z mZde ededeedffdd Zde ede efd d ZGd d d e Zdede efddZedede efddZdede efddZedkrddlZeZedsJdedeedeejedddee dd e!d!d"d#D] Z"ee"d$dqdSdS)%zPEP 656 support. This module implements logic to detect if the currently running Python is linked against musl, and what musl version is used. N)IOIterator NamedTupleOptionalTupleffmtreturn.cCst||t|SN)structunpackreadcalcsize)rrr6/usr/lib/python3/dist-packages/packaging/_musllinux.py_read_unpackedsrc Csb|dzt|d}Wn tjyYdSw|ddtdkr$dS|tddzdd d |d\}}}Wn tyEYdSwtj|}zt||\}}}}}}} Wn tjydYdSwt | dD]C} |||| z |t||\} } } Wn tjyYdSw| d krqk|| t | |  d }d |vrdS|SdS)zDetect musl libc location by parsing the Python executable. Based on: https://gist.github.com/lyssdod/f51579ae8d93c8657a5564aefc2ffbca ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html r16BNsELFHHI)IIIIHHHIIIIIIII)rrr)QQQIHHHIIQQQQQQ)r)rrmusl)seekrr errortuplerKeyErroroperator itemgetterrangeosfsdecoder strip)ridente_fmtp_fmtp_idxp_get_e_phoff e_phentsizee_phnumip_typep_offsetp_filesz interpreterrrr_parse_ld_musl_from_elfsN    r7c@seZdZUeed<eed<dS) _MuslVersionmajorminorN)__name__ __module__ __qualname__int__annotations__rrrrr8Gs  r8outputcCsxdddd|DD}t|dks|ddddkr dStd |d }|s,dStt|d t|dd S) NcSsg|]}|r|qSrr.0nrrr Msz'_parse_musl_version..css|]}|VqdSr )r(rArrr Msz&_parse_musl_version..rrrrzVersion (\d+)\.(\d+)r)r9r:) splitlineslenrematchr8r>group)r@linesmrrr_parse_musl_versionLs  rM executablec Cst'}z |t|d}WntyYWddSwt|}Wdn1s.wY|s7dStj|gtjdd}t |j S)a`Detect currently-running musl runtime version. This is done by checking the specified executable's dynamic linking information, and invoking the loader to parse its output for a version string. If the loader is musl, the output would be something like:: musl libc (x86_64) Version 1.2.2 Dynamic Program Loader rbNT)stderruniversal_newlines) contextlib ExitStack enter_contextopenOSErrorr7 subprocessrunPIPErMrP)rNstackrldprocrrr_get_musl_versionVs    r]archccsJttj}|dur dSt|jddD]}d|jd|d|VqdS)aTGenerate musllinux tags compatible to the current platform. :param arch: Should be the part of platform tag after the ``linux_`` prefix, e.g. ``x86_64``. The ``linux_`` prefix is assumed as a prerequisite for the current platform to be musllinux-compatible. :returns: An iterator of compatible musllinux tags. N musllinux_r.)r]sysrNr%r:r9)r^sys_muslr:rrr platform_tagsns rc__main__zlinux-z not linuxzplat:zmusl:ztags: )endz[.-]r.-rr_z )#__doc__rR functoolsr#r&rHr rWratypingrrrrrbytesstrr>rr7r8rM lru_cacher]rcr; sysconfig get_platformplat startswithprintrNsubsplittrrrrs8"1   "