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

Python Enhancement Proposals

PEP 600 – Zukünftige ‘manylinux’-Plattform-Tags für portable Linux-Build-Distributionen

Autor:
Nathaniel J. Smith <njs at pobox.com>, Thomas Kluyver <thomas at kluyver.me.uk>
Sponsor:
Paul Moore <p.f.moore at gmail.com>
BDFL-Delegate:
Paul Moore <p.f.moore at gmail.com>
Discussions-To:
Discourse thread
Status:
Final
Typ:
Standards Track
Thema:
Packaging
Erstellt:
03-Mai-2019
Post-History:
03-Mai-2019
Ersetzt:
513, 571, 599
Resolution:
Discourse-Nachricht

Inhaltsverzeichnis

Zusammenfassung

Diese PEP schlägt ein Schema für neue 'manylinux'-Wheel-Tags vor, die definiert werden können, ohne dass für jeden spezifischen Tag eine eigene PEP erforderlich ist, ähnlich wie Windows- und macOS-Tags bereits funktionieren. Dies ermöglicht es Paket-Maintainern, neue Tags schneller zu nutzen, während die begrenzte Zeit von Freiwilligen besser genutzt wird.

Nicht-Ziele sind: Umgang mit Nicht-glibc-basierten Plattformen; Integration mit externen Paketmanagern oder Umgang mit externen Abhängigkeiten wie CUDA; manylinux-Tags anspruchsvoller zu gestalten als ihre Windows/macOS-Entsprechungen; etwas anderes zu tun, als unseren bestehenden, erprobten Ansatz zu nehmen und ihn zu optimieren. Dies sind wichtige Themen, und andere PEPs können sie in Zukunft behandeln, aber für diese PEP gehören sie nicht zum Umfang.

Begründung

Python-Benutzer schätzen es, wenn PyPI vor-kompilierte Pakete für ihre Plattform hat, da dies die Installation schnell und einfach macht. Die Verteilung von vor-kompilierten Binärdateien unter Linux ist jedoch aufgrund der Vielfalt der Linux-basierten Plattformen eine Herausforderung. Zum Beispiel verwenden Debian, Android und Alpine alle den Linux-Kernel, aber mit radikal unterschiedlichen Userspace-Bibliotheken, was es schwierig oder unmöglich macht, ein einziges Wheel zu erstellen, das auf allen dreien funktioniert. Diese Komplexität hat dazu geführt, dass viele frühere Diskussionen über Linux Wheels ins Stocken geraten sind.

Das "manylinux"-Projekt war erfolgreich, indem es eine Strategie des rücksichtslosen Pragmatismus verfolgte. Wir wählten eine große, aber beherrschbare Menge von Linux-Plattformen – insbesondere Mainstream-glibc-basierte Distributionen wie Debian, OpenSuSE, Ubuntu, RHEL usw. – und taten dann alles, was nötig war, um Wheels zu erstellen, die auf all diesen Plattformen funktionieren.

Dieser Ansatz erfordert viele Kompromisse. Manylinux-Wheels können sich nur auf externe Bibliotheken verlassen, die eine konsistente ABI beibehalten und universell auf all diesen Distributionen verfügbar sind, was sie in der Praxis auf eine kleine Auswahl von Kernbibliotheken wie glibc und einige andere beschränkt. Wheels müssen auf sorgfältig ausgewählten Plattformen des ältesten möglichen Jahrgangs gebaut werden, unter Verwendung eines Pythons, das selbst in einer sorgfältig gewählten Konfiguration gebaut wurde. Andere gemeinsame Bibliotheksabhängigkeiten müssen in das Wheel gebündelt werden, was einen komplexen Prozess erfordert, um Kollisionen zwischen nicht zusammenhängenden Wheels zu vermeiden. Und schließlich ändern sich die Details dieser Anforderungen im Laufe der Zeit, da neue Distro-Versionen veröffentlicht werden und alte außer Gebrauch geraten.

Es stellt sich heraus, dass diese Anforderungen nicht zu aufwendig sind: Sie sind im Wesentlichen gleichwertig mit dem, was man tun muss, um Windows- oder macOS-Wheels zu liefern, und der manylinux-Ansatz hat bei Paket-Maintainern und Endbenutzern eine beträchtliche Akzeptanz gefunden. Aber jede manylinux-PEP muss einen Weg finden, diese Komplexitäten anzugehen.

In früheren manylinux-PEPs (PEP 513, PEP 571, PEP 599) haben wir dies getan, indem wir versucht haben, in der PEP die genaue Menge an Bibliotheken, Symbolversionen, Python-Konfigurationen usw. niederzuschreiben, von denen wir glaubten, dass sie zu Wheels führen würden, die auf allen Mainstream-glibc-basierten Linux-Systemen funktionieren. Aber das hat mehrere Probleme verursacht

Erstens sollen PEPs im Allgemeinen normative Referenzen sein: Wenn Software nicht mit der PEP übereinstimmt, reparieren wir die Software. Aber in diesem Fall versuchen die PEPs, Linux-Distributionen zu beschreiben, die ein sich bewegendes Ziel sind und unsere PEPs nicht als Einschränkung ihres Verhaltens betrachten. Das bedeutet, dass wir eine unbegrenzte Verpflichtung eingegangen sind, jede manylinux-PEP zu aktualisieren, wann immer sich die Landschaft der Linux-Distributionen ändert. Dies ist eine erhebliche Verpflichtung für unbezahlte Freiwillige, und es ist unklar, ob diese Arbeit für unsere Benutzer einen Mehrwert bringt.

Und zweitens müssen wir jedes Mal, wenn wir manylinux auf einen neueren Bereich unterstützter Plattformen voranbringen oder Unterstützung für eine neue Architektur hinzufügen, einen ziemlich aufwendigen Prozess durchlaufen: eine neue PEP schreiben, die PyPI- und Pip-Codebasen aktualisieren, um den neuen Tag zu erkennen, warten, bis das neue Pip zu den Benutzern gelangt usw. Nichts davon passiert unter Windows/macOS; es ist nur eine Steuer für Linux-Maintainer. Dies verlangsamt die Bereitstellung neuer manylinux-Versionen und verbraucht einen Teil der begrenzten PEP-Review-Bandbreite unserer Community, wodurch der Fortschritt des Python-Packaging-Ökosystems als Ganzes verlangsamt wird. Dies ist besonders problematisch für weniger beliebte Architekturen, die weniger freiwillige Ressourcen haben, um diese Hürden zu überwinden.

Wie können wir das beheben?

Eine manylinux-PEP muss drei Hauptzielgruppen ansprechen

  • Paket-Installer, wie Pip, müssen in der Lage sein zu bestimmen, welche Wheel-Tags mit dem System kompatibel sind, auf dem sie laufen. Dies erfordert einen automatisierten Prozess zur Introspektion des Systems und dessen Abgleich mit Wheel-Tags.
  • Paket-Indizes, wie PyPI, müssen in der Lage sein zu validieren, welche Wheel-Tags gültig sind. Im Allgemeinen reicht dazu eine Liste gültiger Tags oder ein Regex, das sie abgleicht, aus, ohne dass Kenntnisse über die tatsächliche Semantik einzelner Tags erforderlich sind. (Aber siehe die Diskussion über Upload-Verifizierung unten.)
  • Paket-Maintainer müssen in der Lage sein, Wheels zu erstellen, die den Anforderungen eines bestimmten Wheel-Tags entsprechen.

Hier ist die entscheidende Erkenntnis hinter dieser neuen PEP: Es ist entscheidend, dass verschiedene **Paket-Installer** und **Paket-Indizes** sich darauf einigen, welche manylinux-Tags gültig sind und auf welchen Systemen sie installiert werden, daher brauchen wir eine PEP, um diese zu spezifizieren – aber diese sind unkompliziert und ändern sich zwischen manylinux-Versionen nicht wirklich. Der komplizierte Teil, der sich ständig ändert, ist der Prozess der **Erstellung der Wheels** – aber wenn es mehrere konkurrierende Build-Umgebungen gibt, spielt es **keine Rolle**, ob sie exakt die gleichen Regeln verwenden, solange sie alle Wheels produzieren, die auf Endbenutzersystemen funktionieren. Daher brauchen wir keinen Interoperabilitätsstandard für die Erstellung von Wheels, also müssen wir die Details nicht in einer PEP festhalten.

Um uns weiter zu überzeugen, dass dieser Ansatz funktioniert, schauen wir uns noch einmal an, wie wir Wheels unter Windows und macOS handhaben: Die PEPs beschreiben, welche Tags gültig sind und auf welchen Systemen sie funktionieren sollen, aber nicht, wie man Wheels für diese Plattformen tatsächlich erstellt. Und in der Praxis müssen Sie, wenn Sie Windows- oder macOS-Wheels verteilen möchten, möglicherweise einige komplizierte und schlecht dokumentierte Hürden nehmen, um Abhängigkeiten zu bündeln, den richtigen Bereich von OS-Versionen anzuzielen usw. Aber das System funktioniert, und der Weg zur Verbesserung besteht darin, bessere Dokumentation zu schreiben und bessere Tools zu bauen; niemand denkt, dass der Weg, Windows-Wheels besser funktionieren zu lassen, darin besteht, eine PEP zu veröffentlichen, die beschreibt, welche Symbole Microsoft in seinen Bibliotheken enthalten sollte und wie sein Linker funktionieren sollte. Diese PEP erweitert diese Philosophie auch auf manylinux.

Spezifikation

Kern-Definition

Tags, die das neue Schema verwenden, werden aussehen wie

manylinux_2_17_x86_64

Oder allgemeiner

manylinux_${GLIBCMAJOR}_${GLIBCMINOR}_${ARCH}

Dieser Tag ist ein Versprechen: Der Ersteller des Wheels verspricht, dass das Wheel auf jeder Mainstream-Linux-Distribution funktioniert, die glibc-Version ${GLIBCMAJOR}.${GLIBCMINOR} oder neuer verwendet und bei der ${ARCH} mit dem Rückgabewert von distutils.util.get_platform() übereinstimmt. (Weitere Details zu Architektur-Tags finden Sie in PEP 425.)

Wenn ein Benutzer dieses Wheel in einer Umgebung installiert, die diese Anforderungen erfüllt, und es funktioniert nicht, dann entspricht dieses Wheel nicht dieser Spezifikation. Dies sollte als Fehler im Wheel betrachtet werden, und es liegt in der Verantwortung des Erstellers des Wheels, nach einer Lösung zu suchen (möglicherweise mit Hilfe der breiteren Community).

Das Wort "Mainstream" ist absichtlich etwas vage und sollte expansiv interpretiert werden. Das Ziel ist es, seltsame selbstgebaute Linux-Systeme auszuschließen; im Allgemeinen sollte jede Distribution, von der Sie tatsächlich gehört haben, als "Mainstream" betrachtet werden. Wir bieten auch eine Möglichkeit für Maintainer von "seltsamen" Distributionen, diese Prüfung manuell zu überschreiben, obwohl wir aufgrund der Erfahrungen mit früheren manylinux-PEPs nicht erwarten, dass diese Funktion viel genutzt wird.

Und schließlich müssen konforme Wheels "gut mit anderen spielen", d.h. die Installation eines manylinux-Wheels darf andere nicht verwandte Pakete nicht brechen.

Jede Methode zur Erzeugung von Wheels, die diese Kriterien erfüllt, ist akzeptabel. In der Praxis erwarten wir jedoch, dass das Auditwheel-Projekt eine aktuelle Sammlung von Tools und Build-Images für die Erstellung von manylinux-Wheels pflegt, sowie Dokumentation darüber, wie sie funktionieren und wie man sie verwendet, und dass die meisten Maintainer diese verwenden möchten. Die aktuellsten Informationen zum Erstellen von manylinux-Wheels, einschließlich Empfehlungen, welche Build-Images verwendet werden sollen, finden Sie unter https://packaging.python.org.

Da diese Anforderungen recht hochschwellig sind, hier einige Beispiele, wie sie sich in spezifischen Situationen auswirken

Beispiel: Wenn ein Wheel als manylinux_2_17_x86_64 getaggt ist, aber Symbole verwendet, die erst in glibc 2.18 hinzugefügt wurden, dann funktioniert dieses Wheel nicht auf Systemen mit glibc 2.17. Daher können wir schlussfolgern, dass dieses Wheel gegen diese Spezifikation verstößt.

Beispiel: Bis ca. 2017 enthielten alle wichtigen Linux-Distributionen libncursesw.so.5 als Teil ihrer Standardinstallation. Bis zu diesem Datum war ein Wheel, das mit libncursesw.so.5 verknüpft war, konform mit dieser Spezifikation. Dann wechselten die Distributionen zu ncurses 6, das einen anderen Namen und eine inkompatible ABI hat und libncursesw.so.5 nicht mehr standardmäßig installierte. Also nach diesem Datum war ein Wheel, das mit libncursesw.so.5 verknüpft war, nicht mehr konform mit dieser Spezifikation.

Beispiel: Der Linux ELF-Linker platziert alle Shared-Library-SONAMEs in einen einzigen prozessglobalen Namensraum. Wenn unabhängige Wheels denselben SONAME für ihre gebündelten Bibliotheken verwenden, könnten sie kollidieren und die falsche Bibliotheksversion verwenden, was gegen die Regel "gut mit anderen spielen" verstoßen würde. Daher verlangt diese Spezifikation, dass Wheels global eindeutige Namen für alle gebündelten Bibliotheken verwenden. (Auditwheel erreicht dies derzeit, indem es alle gebündelten Bibliotheken umbenennt, um einen global eindeutigen Hash einzuschließen.)

Beispiel: Wir haben beobachtet, dass bestimmte Wheels C++ auf eine Weise verwenden, die andere Pakete beeinträchtigt, und zwar über einen unklaren Mechanismus. Dies ist ebenfalls ein Verstoß gegen die Regel "gut mit anderen spielen", daher sind diese Wheels nicht konform mit dieser Spezifikation.

Beispiel: Die imaginäre Architektur LEG v7 hat sowohl Big-Endian- als auch Little-Endian-Varianten. Big-Endian-Binärdateien erfordern ein Big-Endian-System, und Little-Endian-Binärdateien erfordern ein Little-Endian-System. Aber leider wurde festgestellt, dass aufgrund eines Fehlers in PEP 425 beide Varianten denselben Architektur-Tag legv7 verwenden. Dies macht es unmöglich, ein konformes manylinux_2_17_legv7 Wheel zu erstellen: Egal was wir tun, es wird auf den Systemen einiger Benutzer abstürzen. Also schreiben wir eine neue PEP, die die Architektur-Tags legv7le und legv7be definiert; jetzt können wir manylinux LEG v7 Wheels ausliefern.

Beispiel: Es gibt auch eine LEG v8. Sie hat ebenfalls Big-Endian- und Little-Endian-Varianten. Aber glücklicherweise stellt sich heraus, dass PEP 425 bereits das Richtige für LEG v8 tut, so dass LEG v8-Enthusiasten sofort manylinux_2_17_legv8le und manylinux_2_17_legv8be Wheels ausliefern können, sobald diese PEP implementiert ist, auch wenn die Autoren dieser PEP überhaupt nichts über LEG v8 wissen.

Legacy manylinux-Tags

Die bestehenden manylinux-Tags werden als Aliase für neue Tag-Typen neu definiert

  • manylinux1_x86_64 ist jetzt ein Alias für manylinux_2_5_x86_64
  • manylinux1_i686 ist jetzt ein Alias für manylinux_2_5_i686
  • manylinux2010_x86_64 ist jetzt ein Alias für manylinux_2_12_x86_64
  • manylinux2010_i686 ist jetzt ein Alias für manylinux_2_12_i686
  • manylinux2014_x86_64 ist jetzt ein Alias für manylinux_2_17_x86_64
  • manylinux2014_i686 ist jetzt ein Alias für manylinux_2_17_i686
  • manylinux2014_aarch64 ist jetzt ein Alias für manylinux_2_17_aarch64
  • manylinux2014_armv7l ist jetzt ein Alias für manylinux_2_17_armv7l
  • manylinux2014_ppc64 ist jetzt ein Alias für manylinux_2_17_ppc64
  • manylinux2014_ppc64le ist jetzt ein Alias für manylinux_2_17_ppc64le
  • manylinux2014_s390x ist jetzt ein Alias für manylinux_2_17_s390x

Diese Neudefinition ist größtenteils ein No-Op, beeinflusst aber einige Dinge

  • Zuvor hatten wir eine unbegrenzte und wachsende Verpflichtung, jede manylinux-PEP zu aktualisieren, wann immer eine neue Linux-Distribution veröffentlicht wurde, für den Rest der Zeit. Indem wir diese PEP zu den älteren Tags normativ machen, entfällt diese Verpflichtung. Wenn diese PEP akzeptiert wird, erhalten die früheren manylinux-PEPs ein letztes Update, das darauf hinweist, dass sie nicht mehr gepflegt werden und auf diese PEP verweist.
  • Die "gut mit anderen spielen"-Regel war immer beabsichtigt, aber frühere PEPs hatten sie nicht explizit formuliert; jetzt ist sie explizit.
  • Frühere PEPs gingen davon aus, dass glibc 3.x mit glibc 2.x inkompatibel sein könnte, daher haben wir die Kompatibilität zwischen einem System und einem Tag mit Logik wie folgt überprüft
    sys_major == tag_major and sys_minor >= tag_minor
    

    Kürzlich haben uns die glibc-Maintainer mitgeteilt, dass wir davon ausgehen sollten, dass glibc die Abwärtskompatibilität auf unbestimmte Zeit beibehält, auch wenn die Hauptversionsnummer erhöht wird. Daher ist die neue Prüfung auf Kompatibilität

    (sys_major, sys_minor) >= (tag_major, tag_minor)
    

Paket-Installer

Im Allgemeinen sollten Paket-Installer manylinux-Wheels auf Systemen installieren, die eine entsprechende glibc und Architektur haben, und nicht anderweitig. Wenn mehrere kompatible manylinux-Wheels verfügbar sind, sollte das Wheel mit der höchsten glibc-Version bevorzugt werden, um neuere Compiler und glibc-Funktionen zu nutzen.

Darüber hinaus folgen wir früheren Spezifikationen und erlauben Python-Distributoren, diese Prüfung manuell zu überschreiben, indem sie ein _manylinux-Modul zu ihrer Standardbibliothek hinzufügen. Wenn dieses Paket importierbar ist und eine Funktion namens manylinux_compatible definiert, dann sollten Paket-Installer diese Funktion aufrufen und die Hauptversion, Nebenversion und Architektur aus dem manylinux-Tag übergeben. Diese gibt entweder einen booleschen Wert zurück, der angibt, ob Wheels mit dem gegebenen Tag als kompatibel mit dem aktuellen System gelten sollten, oder None, um anzuzeigen, dass die Standardlogik verwendet werden sollte.

Zur Kompatibilität mit früheren Spezifikationen: Wenn der Tag genau manylinux1 oder manylinux_2_5 ist, prüfen wir das Modul auch auf ein boolesches Attribut manylinux1_compatible. Wenn die Tag-Version genau manylinux2010 oder manylinux_2_12 ist, prüfen wir das Modul auch auf ein boolesches Attribut manylinux2010_compatible. Und wenn die Tag-Version genau manylinux2014 oder manylinux_2_17 ist, prüfen wir das Modul auch auf ein boolesches Attribut manylinux2014_compatible. Wenn sowohl das neue als auch das alte Attribut definiert sind, hat manylinux_compatible Vorrang.

Hier ist ein Beispielcode. Sie müssen diesen Code nicht unbedingt verwenden, aber Sie können ihn als Referenz verwenden, wenn Sie Fragen zu den genauen Semantiken haben

LEGACY_ALIASES = {
    "manylinux1_x86_64": "manylinux_2_5_x86_64",
    "manylinux1_i686": "manylinux_2_5_i686",
    "manylinux2010_x86_64": "manylinux_2_12_x86_64",
    "manylinux2010_i686": "manylinux_2_12_i686",
    "manylinux2014_x86_64": "manylinux_2_17_x86_64",
    "manylinux2014_i686": "manylinux_2_17_i686",
    "manylinux2014_aarch64": "manylinux_2_17_aarch64",
    "manylinux2014_armv7l": "manylinux_2_17_armv7l",
    "manylinux2014_ppc64": "manylinux_2_17_ppc64",
    "manylinux2014_ppc64le": "manylinux_2_17_ppc64le",
    "manylinux2014_s390x": "manylinux_2_17_s390x",
}

def manylinux_tag_is_compatible_with_this_system(tag):
    # Normalize and parse the tag
    tag = LEGACY_ALIASES.get(tag, tag)
    m = re.match("manylinux_([0-9]+)_([0-9]+)_(.*)", tag)
    if not m:
        return False
    tag_major_str, tag_minor_str, tag_arch = m.groups()
    tag_major = int(tag_major_str)
    tag_minor = int(tag_minor_str)

    if not system_uses_glibc():
        return False
    sys_major, sys_minor = get_system_glibc_version()
    if (sys_major, sys_minor) < (tag_major, tag_minor):
        return False
    sys_arch = get_system_arch()
    if sys_arch != tag_arch:
        return False

    # Check for manual override
    try:
        import _manylinux
    except ImportError:
        pass
    else:
        if hasattr(_manylinux, "manylinux_compatible"):
            result = _manylinux.manylinux_compatible(
                tag_major, tag_minor, tag_arch,
            )
            if result is not None:
                return bool(result)
        else:
            if (tag_major, tag_minor) == (2, 5):
                if hasattr(_manylinux, "manylinux1_compatible"):
                    return bool(_manylinux.manylinux1_compatible)
            if (tag_major, tag_minor) == (2, 12):
                if hasattr(_manylinux, "manylinux2010_compatible"):
                    return bool(_manylinux.manylinux2010_compatible)

    return True

Paket-Indizes

Die genaue Menge der von PyPI oder einem anderen Paketindex akzeptierten Wheel-Tags ist eine Politikfrage und liegt bei den Maintainern dieses Indexes. Wir empfehlen jedoch, dass Paketindizes alle Wheels akzeptieren, deren Plattform-Tag den folgenden Regexs entspricht

  • manylinux1_(x86_64|i686)
  • manylinux2010_(x86_64|i686)
  • manylinux2014_(x86_64|i686|aarch64|armv7l|ppc64|ppc64le|s390x)
  • manylinux_[0-9]+_[0-9]+_(.*)

Paketindizes können zusätzliche Anforderungen stellen; zum Beispiel können sie hochgeladene Wheels auditieren und solche zurückweisen, die bekannte Probleme enthalten, wie z.B. ein manylinux_2_17-Wheel, das auf Symbole aus späteren glibc-Versionen verweist, oder Abhängigkeiten von externen Bibliotheken, von denen bekannt ist, dass sie nicht auf allen Systemen vorhanden sind. Oder ein Paketindex kann sich entscheiden, konservativ zu sein und Wheels mit dem Tag manylinux_2_999 abzulehnen, mit der Begründung, dass niemand weiß, wie die Linux-Distributionslandschaft aussehen wird, wenn glibc 2.999 veröffentlicht wird. Wir überlassen die Details solcher Prüfungen der Entscheidung der Paketindex-Maintainer.

Abgelehnte Alternativen

Fortsetzung der manylinux20XX-Reihe: Wie oben diskutiert, führt dies zu deutlich aufwendigeren, langsameren und komplexeren Rollouts neuer Versionen. Und obwohl es zwei Bereiche gibt, in denen es auf den ersten Blick einige kompensierende Vorteile zu geben scheint, erweist sich dies bei genauerer Betrachtung als nicht der Fall.

Erstens zwingt uns dies, menschenlesbare Beschreibungen der Funktionsweise von Linux-Distributionen im Text der PEP zu erstellen. Aber das ist weniger wertvoll, als es auf den ersten Blick scheint, und kann durch den neuen "dauerhaften" Ansatz ohnehin besser gehandhabt werden.

Wenn Sie Wheels erstellen möchten, ist die wichtigste Ressource ein Tutorial zur Verwendung der Build-Images und der damit verbundenen Tools. Wenn Sie Unterstützung für ein neues Build-Profil hinzufügen oder einen Konkurrenten zu Auditwheel erstellen möchten, sind Ihre besten Ressourcen der Auditwheel-Quellcode und der Issue-Tracker, die immer detaillierter, präziser und zuverlässiger sein werden als eine Zusammenfassungsspezifikation, die in Englisch und ohne Tests verfasst ist. Dokumentation wie die alten manylinux20XX-PEPs fügt einen Mehrwert hinzu! Aber in beiden Fällen dient sie hauptsächlich als sekundäre Referenz, um Übersicht und Kontext zu bieten.

Darüber hinaus ist der PEP-Prozess schlecht geeignet, um diese Art von Referenzdokumentation zu pflegen – es gibt einen Grund, warum wir das Pip-Benutzerhandbuch nicht im PEPs-Repository aufbewahren! Die Auditwheel-Maintainer sind am besten geeignet, um zu verstehen, welche Arten von Dokumentation für ihre Benutzer nützlich sind und diese Dokumentation im Laufe der Zeit zu pflegen. Zum Beispiel gibt es erhebliche Überschneidungen zwischen den verschiedenen manylinux-Versionen, und der PEP-Prozess zwingt uns derzeit, dies zu handhaben, indem wir alles zwischen einer wachsenden Liste von Dokumenten kopieren. Stattdessen könnten die Auditwheel-Maintainer die gemeinsamen Teile in ein einziges Stück gemeinsamer Dokumentation auslagern.

Eine verwandte Bedenken war, dass es mit dem dauerhaften Ansatz für Paket-Maintainer schwieriger werden könnte, zu entscheiden, welches Build-Profil sie ansteuern sollen: Anstatt zwischen manylinux1, manylinux2010, manylinux2014, ... wählen zu müssen, haben sie nun eine größere Auswahl an Optionen wie manylinux_2_5, manylinux_2_6, ..., manylinux_2_20, ... Aber auch hier glauben wir nicht, dass dies ein Problem sein wird. In beiden Systemen werden die meisten Paket-Maintainer nicht damit beginnen, PEPs zu lesen und sie von Grund auf zu implementieren. Wenn Sie ein besonders erfahrener und ehrgeiziger Paket-Maintainer sind, der eine neue Version oder eine neue Architektur ansteuern muss, bietet der dauerhafte Ansatz zusätzliche Flexibilität. Aber für normale alltägliche Maintainer erwarten wir, dass sie mit einem Tutorial wie packaging.python.org beginnen und aus bestehenden Build-Images wählen. Ein Tutorial kann genauso gut manylinux_2_17 empfehlen wie manylinux2014, und wir erwarten, dass die tatsächliche Menge an bereitgestellten Build-Images in beiden Fällen identisch ist. Und wieder, indem wir diese Dokumentation an der richtigen Stelle pflegen, anstatt sie im PEPs-Repository zu verwalten, erwarten wir, dass wir am Ende eine qualitativ hochwertigere und zweckmäßigere Dokumentation erhalten.

Schließlich haben einige Teilnehmer darauf hingewiesen, dass es sehr schön ist, ein Wheel ansehen zu können und definitiv zu sagen, ob es den Anforderungen der Spezifikation entspricht. Mit dem neuen "dauerhaften" Ansatz können wir niemals mit 100%iger Sicherheit sagen, dass ein Wheel der Spezifikation entspricht, da dies von den Linux-Distributionen abhängt. Als Ingenieure haben wir eine wohlbegründete Abneigung gegen diese Art von Unsicherheit.

Allerdings: Wie die obigen Beispiele zeigen, können wir definitiv feststellen, wann ein Wheel die Spezifikation *nicht* erfüllt, was sich als das herausstellt, was praktisch wichtig ist. Und in der Praxis ändern wir mit dem manylinux20XX-Ansatz jedes Mal die Spezifikation, wenn sich Distributionen ändern; es dauert etwas länger. Selbst wenn ein Wheel heute konform war, könnte es morgen nicht mehr konform sein. Das ist frustrierend, aber leider ist diese Unsicherheit unvermeidlich, wenn Ihr Hauptanliegen darin besteht, funktionierende Wheels an Benutzer zu verteilen.

Selbst an den Punkten, an denen der alte Ansatz anfangs Vorteile zu haben scheint, erwarten wir, dass der neue Ansatz genauso gut oder besser abschneidet.

Umstieg auf dauerhafte Tags, aber weiterhin eine PEP für jede Version schreiben: Dies wurde als eine Art Hybrid vorgeschlagen, um einige der Vorteile des dauerhaften Tagging-Systems zu nutzen – wie einfachere Rollouts neuer Versionen –, während die Vorteile des manylinux20XX-Schemas beibehalten werden, wie z.B. uns zu zwingen, Dokumentation über Linux-Distributionen zu schreiben, Optionen für Paket-Maintainer zu vereinfachen und definitiv sagen zu können, wann ein Wheel der Spezifikation entspricht. Aber wie oben diskutiert, stellt sich bei genauerer Betrachtung heraus, dass diese Vorteile größtenteils illusorisch sind. Und dies erbt auch erhebliche *Nachteile* des manylinux20XX-Schemas, wie z.B. die Schaffung unbefristeter Verpflichtungen zur Aktualisierung einer wachsenden Liste von kopierten PEPs.

Auditwheel normativ machen: Eine weitere in Betracht gezogene Möglichkeit war, Auditwheel zur normativen Referenz für die Definition von manylinux zu machen, d.h. ein Wheel wäre konform, wenn und nur wenn auditwheel check ohne Fehler abgeschlossen wird. Dies wurde abgelehnt, da der Sinn von Packaging-PEPs darin besteht, die Interoperabilität zwischen Tools zu definieren und nicht spezifische Tools zu segnen.

Hinzufügen von zusätzlichen Wörtern zum Tag-String: Ein weiterer von uns betrachteter Vorschlag war, zusätzliche Wörter zum Wheel-Tag hinzuzufügen, z.B. manylinux_glibc_2_17 anstelle von manylinux_2_17. Die Motivation wäre, die Tür für andere Arten von Versionierungsheuristiken in der Zukunft offen zu lassen – zum Beispiel könnten wir manylinux_glibc_$VERSION und manylinux_alpine_$VERSION haben.

Aber "manylinux" war schon immer ein Synonym für "breite Kompatibilität mit Mainstream-glibc-basierten Distributionen"; es für unzusammenhängende Build-Profile wie Alpine wiederzuverwenden, ist verwirrender als hilfreich. Außerdem fanden einige frühe Gutachter, die nicht in den Details des Packagings bewandert sind, das Wort glibc aktiv irreführend, da sie zu dem Schluss kamen, dass es ein System mit *genau* dieser glibc-Version erforderte. Und Tags wie manylinux_$VERSION und alpine_$VERSION haben auch die Vorteile der Parsimonie und Direktheit. Wir werden uns also dafür entscheiden.


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

Zuletzt geändert: 2025-02-01 08:59:27 GMT