Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 656 – Plattform-Tag für Linux-Distributionen, die Musl verwenden

Autor:
Tzu-ping Chung <uranusjr at gmail.com>
Sponsor:
Brett Cannon <brett at python.org>
PEP-Delegate:
Paul Moore <p.f.moore at gmail.com>
Discussions-To:
Discourse thread
Status:
Final
Typ:
Standards Track
Thema:
Packaging
Erstellt:
17-März-2021
Post-History:
17-März-2021, 18-Apr-2021
Resolution:
Discourse-Nachricht

Inhaltsverzeichnis

Zusammenfassung

Dieses PEP schlägt eine neue Plattform-Tag-Serie musllinux für binäre Python-Paketdistributionen für eine Python-Installation vor, die auf musl auf einer Linux-Distribution basiert. Der Tag funktioniert ähnlich wie die in PEP 600 spezifizierten "perennial manylinux"-Plattform-Tags, zielt aber stattdessen auf musl-basierte Plattformen ab.

Motivation

Angesichts der weit verbreiteten Nutzung von Containern gewinnen Distributionen wie Alpine Linux [alpine] mehr an Popularität als je zuvor. Viele von ihnen basieren auf musl [musl], einer anderen libc-Implementierung als glibc, und können daher die bestehenden manylinux-Plattform-Tags nicht verwenden. Dies bedeutet, dass Python-Paketprojekte keine binären Distributionen auf PyPI für sie bereitstellen können. Benutzer solcher Projekte fordern Build-Einschränkungen von diesen Projekten, was eine unnötige Belastung für die Projektbetreuer darstellt.

Begründung

Laut Dokumentation hat musl eine stabile ABI und erhält die Abwärtskompatibilität aufrecht [musl-compatibility] [compare-libcs]. Daher ist garantiert, dass ein gegen eine frühere Version von musl kompiliertes Binärpaket gegen eine neuere musl-Laufzeitumgebung läuft [musl-compat-ml]. Daher verwenden wir ein Schema, das dem auf glibc-Versionen basierenden manylinux-Tag-Schema ähnelt, jedoch gegen musl-Versionen anstelle von glibc.

Die Logik hinter dem neuen Plattform-Tag folgt weitgehend PEP 600 ("perennial manylinux") und erfordert, dass Wheels mit diesem Tag ähnliche Zusagen machen. Weitere Details zur Begründung und zum Design finden Sie in PEP 600.

Die musllinux-Plattform-Tags gelten nur für Python-Interpreter, die dynamisch gegen die musl libc gelinkt und in der Laufzeit-Shared-Library auf einem Linux-Betriebssystem ausgeführt werden. Statisch gelinkte Interpreter oder gemischte Builds mit anderen libc-Implementierungen (wie glibc) sind nicht betroffen und werden durch die in diesem Dokument definierten Plattform-Tags nicht unterstützt. Solche Interpreter sollten keine Kompatibilität mit musllinux-Plattform-Tags beanspruchen.

Spezifikation

Tags mit dem neuen Schema haben die Form

musllinux_${MUSLMAJOR}_${MUSLMINOR}_${ARCH}

Dieser Tag verspricht, dass das Wheel auf jeder Mainstream-Linux-Distribution läuft, die musl-Version ${MUSLMAJOR}.${MUSLMINOR} verwendet, gemäß dem perennialen Design. Alle anderen systembezogenen Abhängigkeitsanforderungen beruhen auf der Definition der Community für die bewusst vage Beschreibung "Mainstream", die in PEP 600 eingeführt wurde. Ein Wheel kann neuere Systemabhängigkeiten verwenden, wenn alle Mainstream-Distributionen, die die angegebene musl-Version verwenden, die Abhängigkeit standardmäßig bereitstellen. Sobald alle Mainstream-Distributionen auf der musl-Version eine bestimmte Abhängigkeitsversion standardmäßig ausliefern, werden Benutzer, die sich auf ältere Versionen verlassen, automatisch aus der Abdeckung dieses musllinux-Tags entfernt.

Auslesen der Musl-Version

Die musl-Versionswerte können durch Ausführung der musl libc Shared-Library, auf der der Python-Interpreter gerade läuft, und Parsen der Ausgabe erhalten werden

import re
import subprocess

def get_musl_major_minor(so: str) -> tuple[int, int] | None:
    """Detect musl runtime version.

    Returns a two-tuple ``(major, minor)`` that indicates musl
    library's version, or ``None`` if the given libc .so does not
    output expected information.

    The libc library should output something like this to stderr::

        musl libc (x86_64)
        Version 1.2.2
        Dynamic Program Loader
    """
    proc = subprocess.run([so], stderr=subprocess.PIPE, text=True)
    lines = (line.strip() for line in proc.stderr.splitlines())
    lines = [line for line in lines if line]
    if len(lines) < 2 or lines[0][:4] != "musl":
        return None
    match = re.match(r"Version (\d+)\.(\d+)", lines[1])
    if match:
        return (int(match.group(1)), int(match.group(2)))
    return None

Es gibt derzeit zwei mögliche Wege, den Speicherort der musl-Bibliothek zu finden, auf die ein Python-Interpreter läuft: entweder mit dem systemeigenen ldd-Befehl [ldd] oder durch Parsen des PT_INTERP-Abschnitts aus dem ELF-Header der ausführbaren Datei [elf].

Formatieren des Tags

Distributionen, die den Tag verwenden, machen ähnliche Zusagen wie in PEP 600 beschrieben, einschließlich

  1. Das Binärpaket funktioniert auf jeder Mainstream-Linux-Distribution mit musl-Version ${MUSLMAJOR}.${MUSLMINOR} oder neuer.
  2. Die ${ARCH} des Binärpakets stimmt mit dem Rückgabewert von sysconfig.get_platform() auf dem Host-System überein, wobei Punkte (.) und Bindestriche (-) durch Unterstriche (_) ersetzt werden, wie in PEP 425 und PEP 427 beschrieben.

Beispielwerte

musllinux_1_1_x86_64   # musl 1.1 running on x86-64.
musllinux_1_2_aarch64  # musl 1.2 running on ARM 64-bit.

Der Wert kann mit dem folgenden Python-Code formatiert werden

import sysconfig

def format_musllinux(musl_version: tuple[int, int]) -> str:
    os_name, sep, arch = sysconfig.get_platform().partition("-")
    assert os_name == "linux" and sep, "Not a Linux"
    arch = arch.replace(".", "_").replace("-", "_")
    return f"musllinux_{musl_version[0]}_{musl_version[1]}_{arch}"

Empfehlungen für Paketindizes

Es wird empfohlen, dass Python-Paket-Repositories, einschließlich PyPI, Plattform-Tags akzeptieren, die dem folgenden regulären Ausdruck entsprechen

musllinux_([0-9]+)_([0-9]+)_([^.-]+)

Python-Paket-Repositories können zusätzliche Anforderungen auferlegen, um Wheels mit bekannten Problemen abzulehnen, einschließlich, aber nicht beschränkt auf

  • Ein musllinux_1_1-Wheel, das Symbole enthält, die nur in musl 1.2 oder neuer verfügbar sind.
  • Ein Wheel, das von externen Bibliotheken abhängt, die nicht als allgemein verfügbar für die Zielgruppe des Paketindex gelten.
  • Ein Plattform-Tag, der Kompatibilität mit einer nicht existierenden musl-Version beansprucht (z. B. musllinux_9000_0).

Solche Richtlinien liegen letztendlich bei den einzelnen Paket-Repositories. Es ist nicht die Absicht des Autors, den Betreuern Einschränkungen aufzuerlegen.

Abwärtskompatibilität

Es gibt keine Abwärtskompatibilitätsprobleme in diesem PEP.

Abgelehnte Ideen

Erstellung eines Plattform-Tags speziell für Alpine Linux

Erfahrungen aus der Vergangenheit mit der manylinux-Tag-Serie zeigen, dass dieser Ansatz zu zeitaufwändig wäre. Der Autor ist der Meinung, dass die Regel "funktioniert gut mit anderen" inklusiver ist und in der Praxis gut funktioniert.

Referenzen


Quelle: https://github.com/python/peps/blob/main/peps/pep-0656.rst

Zuletzt geändert: 2025-02-01 08:55:40 GMT