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

Python Enhancement Proposals

PEP 714 – Umbenennung von dist-info-metadata in der Simple API

Autor:
Donald Stufft <donald at stufft.io>
PEP-Delegate:
Paul Moore <p.f.moore at gmail.com>
Discussions-To:
Discourse thread
Status:
Akzeptiert
Typ:
Standards Track
Thema:
Packaging
Erstellt:
06-Juni 2023
Post-History:
06-Juni 2023
Resolution:
27-Juni 2023

Inhaltsverzeichnis

Zusammenfassung

Dieser PEP benennt die Metadaten um, die von PEP 658 sowohl im HTML- als auch im JSON-Format der Simple API bereitgestellt werden, und gibt Richtlinien für Clients und Server an, wie mit der Umbenennung umzugehen ist.

Motivation

PEP 658 spezifizierte einen Mechanismus zur Bereitstellung der Kerndatenmetadaten einer über die Simple API verfügbaren Artefaktdatei, so dass ein Client die Metadaten abrufen und verwenden konnte, ohne das gesamte Artefakt herunterladen zu müssen. Später wurde PEP 691 verfasst, um die Möglichkeit hinzuzufügen, JSON anstelle von HTML in der Simple API zu verwenden, was die Unterstützung für die PEP 658-Metadaten einschloss.

Leider unterstützte PyPI PEP 658 erst kürzlich, was mit einem Fehler veröffentlicht wurde, bei dem der Schlüssel dist-info-metadata aus PEP 658 in der JSON-Darstellung falsch benannt war, nämlich data-dist-info-metadata. Als jedoch versucht wurde, diesen Fehler zu beheben, wurde entdeckt, dass pip auch einen Fehler hatte, bei dem jede Verwendung von dist-info-metadata in der JSON-Darstellung dazu führte, dass pip mit einer Ausnahme hart abstürzte.

Der Fehler in pip existiert seit mindestens v22.3, was bedeutet, dass er seit etwa 8 Monaten veröffentlicht ist, lange genug, um in Python-Versionen, nachgelagerten Linux-Versionen, in Container und virtuellen Umgebungen usw. übernommen worden zu sein.

Dies bringt uns in die unangenehme Lage, einen Fehler in PyPI zu haben, der nicht behoben werden kann, ohne pip zu brechen, aufgrund eines Fehlers in pip, aber diese Version von pip ist alt genug, um weit verbreitet zu sein. Erschwerend kommt hinzu, dass eine auf diese Weise fehlerhafte pip-Version nichts mehr von PyPI installieren kann, sobald sie ihren Fehler behebt, einschließlich der Installation einer neuen, korrigierten Version von pip.

Begründung

Es gibt 3 Hauptoptionen für einen Weg nach vorn, um diese Fehler zu beheben.

  1. Die Spezifikation nicht ändern, den Fehler in pip beheben, eine gewisse Zeit warten, dann den Fehler in PyPI beheben, wodurch jeder, der ein nicht behobenes pip verwendet, beeinträchtigt wird, so dass er nicht einmal ein neues pip von PyPI installieren kann.
  2. Das Gleiche tun wie in (1), aber PyPI als Sonderfall behandeln, so dass es die PEP 658-Metadaten für pip nicht ausgibt, auch wenn sie verfügbar sind. Dies ermöglicht es den Benutzern, pip zu aktualisieren, wenn sie eine fehlerhafte Version verwenden, aber nichts weiter.
  3. Die Spezifikation ändern, um den Schlüssel zu vermeiden, mit dem pip derzeit nicht umgehen kann, so dass PyPI diesen Schlüssel ausgeben kann und eine neue pip-Version veröffentlicht werden kann, um diesen Schlüssel zu nutzen.

Dieser PEP wählt (3), geht aber noch einen Schritt weiter und benennt auch den Schlüssel in der HTML-Darstellung um.

Normalerweise ändern wir keine Spezifikationen aufgrund von Fehlern, die nur eine bestimmte Implementierung betreffen, es sei denn, die Spezifikation selbst ist fehlerhaft, was hier nicht der Fall ist: Die Spezifikation ist in Ordnung und dies sind nur echte Fehler in pip und PyPI.

Wir entscheiden uns jedoch dafür aus 4 Gründen

  1. Fehler, die pip und PyPI betreffen, haben im Vergleich zu jeder anderen Client- oder Repository-Kombination einen überproportional großen Einfluss.
  2. Die Auswirkung einer fehlerhaften Funktionalität ist, dass Installationen überhaupt nicht funktionieren, anstatt sich auf irgendeine Weise elegant zu verschlechtern.
  3. Das Feature, das durch diese Fehler blockiert wird, ist für die Fähigkeit, Abhängigkeiten schnell und effizient von PyPI mit pip aufzulösen, von großer Bedeutung. Eine lange Verzögerung, während wir auf das Auslaufen fehlerhafter pip-Versionen warten, wäre zum Nachteil des gesamten Ökosystems.
  4. Die Nachteile einer Änderung der Spezifikation sind ziemlich begrenzt, da wir nicht davon ausgehen, dass die Unterstützung hierfür weit verbreitet ist, so dass nur eine begrenzte Anzahl von Projekten betroffen ist.

Spezifikation

Die Schlüsselwörter "MUSS", "DARF NICHT", "ERFORDERLICH", "SOLL", "SOLL NICHT", "EMPOHLEN", "KANN" und "OPTIONAL" sind in diesem Dokument wie in RFC 2119 beschrieben.

Server

Die PEP 658-Metadaten müssen bei der Verwendung in der HTML-Darstellung der Simple API mit dem Attributnamen data-core-metadata ausgegeben werden, wobei die unterstützten Werte gleich bleiben.

Die PEP 658-Metadaten müssen bei der Verwendung in der PEP 691 JSON-Darstellung der Simple API mit dem Schlüssel core-metadata ausgegeben werden, wobei die unterstützten Werte gleich bleiben.

Um Clients zu unterstützen, die die vorherigen Schlüsselnamen verwendet haben, DARF die HTML-Darstellung auch mit dem data-dist-info-metadata-Attribut ausgegeben werden, und wenn dies geschieht, MUSS es dem Wert von data-core-metadata entsprechen.

Clients

Clients, die eine der HTML-Darstellungen der Simple API konsumieren, MÜSSEN die PEP 658-Metadaten aus dem Schlüssel data-core-metadata lesen, falls vorhanden. Sie KÖNNEN optional das ältere data-dist-info-metadata verwenden, wenn es vorhanden ist, aber data-core-metadata nicht.

Clients, die die JSON-Darstellung der Simple API konsumieren, MÜSSEN die PEP 658-Metadaten aus dem Schlüssel core-metadata lesen, falls vorhanden. Sie KÖNNEN optional den älteren Schlüssel dist-info-metadata verwenden, wenn er vorhanden ist, aber core-metadata nicht.

Abwärtskompatibilität

Es gibt einen geringfügigen Kompatibilitätsbruch in diesem PEP, da Clients, die derzeit die bestehenden Metadatenschlüssel korrekt verarbeiten, die neueren Metadatenschlüssel nicht automatisch verstehen werden, aber sie sollten sich ordnungsgemäß verhalten und einfach so tun, als ob die PEP 658-Metadaten nicht existieren.

Ansonsten sollte es keine Kompatibilitätsprobleme mit diesem PEP geben.

Abgelehnte Ideen

Die Spezifikation unverändert lassen und Korrekturen in PyPI und/oder pip vornehmen

Wir sind der Meinung, dass die durch PEP 658 ermöglichten Verbesserungen für die Leistungsfähigkeit der Auflösung von Abhängigkeiten von PyPI sehr wichtig sind und wir möchten sie so schnell wie möglich bereitstellen können.

Leider können wir diese aufgrund der Natur dieser Fehler nicht so wie sie sind bereitstellen, ohne weit verbreitete und verwendete Versionen von pip zu brechen. Die Brüche in diesem Fall wären so gravierend, dass betroffene Benutzer nicht einmal ihre pip-Version zum Beheben des Problems direkt aktualisieren könnten, sondern müssten zuerst pip manuell auf andere Weise herunterladen (z. B. get-pip.py).

Dies ist etwas, das PyPI ohne eine Möglichkeit zur Minderung dieser Brüche für diese Benutzer nicht tun möchte. Ohne eine angemessene Minderungsstrategie müssten wir warten, bis diese Versionen von pip nicht mehr auf PyPI verwendet werden, was wahrscheinlich 5+ Jahre dauern würde.

Es gibt ein paar mögliche Minderungsstrategien, die wir hätten anwenden können, aber wir haben sie ebenfalls abgelehnt.

Minderung: Sonderfall pip

Die Brüche sind besonders schlimm, da sie Benutzern sogar daran hindern, pip zu aktualisieren, um eine nicht fehlerhafte pip-Version zu erhalten. Ein Befehl wie pip install --upgrade pip würde also fehlschlagen. Wir könnten dies mildern, indem wir PyPI pip selbst als Sonderfall behandelt, so dass der JSON-Endpunkt niemals die PEP 658-Metadaten zurückgibt und das oben Genannte weiterhin funktioniert.

Dieser PEP lehnt diese Idee ab, da zwar der einfache Befehl zur Aktualisierung von pip funktionieren würde, aber wenn der Benutzer *irgendetwas* anderes in diesen Befehl zur Aktualisierung aufnehmen würde, würde der Befehl wieder fehlschlagen, was wir immer noch als zu großen Bruch betrachten.

Darüber hinaus tritt dieser Fehler zwar zufällig gerade mit PyPI auf, aber es ist wirklich ein Fehler, der bei jedem PEP 691-Repository auftreten würde, das die PEP 658-Metadaten korrekt bereitstellt. Dies würde bedeuten, dass jedes Repository diesen Sonderfall für pip tragen müsste.

Minderung: Server verwenden User-Agent-Erkennung

pip fügt seine Versionsnummer in seinen User-Agent ein, was bedeutet, dass der Server die Versionsnummer erkennen und unterschiedliche Antworten basierend auf dieser Versionsnummer liefern könnte, damit wir die PEP 658-Metadaten nicht an fehlerhafte pip-Versionen liefern.

Dieser PEP lehnt diese Idee ab, da die Unterstützung der User-Agent-Erkennung zu schwierig zu implementieren ist, um sie in einer sinnvollen Weise zu realisieren.

  1. Auf PyPI verlassen wir uns stark auf das Caching der Simple API in unserem CDN. Wenn wir die Antworten basierend auf dem User-Agent variieren würden, würde unser CDN-Cache eine Explosion von Cache-Schlüsseln für denselben Inhalt haben, was die Wahrscheinlichkeit erhöht, dass eine bestimmte Anfrage nicht gecacht wird und auf unsere Backend-Server zurückfällt, die viel höher skalieren müssten, um die Last zu bewältigen.
  2. PyPI *könnte* die User-Agent-Erkennung unterstützen, indem es den Accept-Header der Anfrage modifiziert, so dass diese Versionen nur die HTML-Version akzeptieren, was uns erlaubt, die CDN-Cache-Schlüssel beizubehalten. Dies beeinflusst jedoch keine nachgelagerten Caches von PyPI, einschließlich des HTTP-Caches von pip, der möglicherweise JSON-Versionen für diese Anfragen gecacht hätte und wir würden kein Vary auf User-Agent ausgeben, damit diese wissen, dass es nicht akzeptabel ist, diese Caches zu teilen, und das Hinzufügen eines Vary: User-Agent für nachgelagerte Caches hätte das gleiche Problem wie (1), aber für nachgelagerte Caches anstelle unseres CDN-Caches.
  3. Der pip-Fehler ist letztendlich nicht PyPI-spezifisch, er betrifft jedes Repository, das PEP 691 und PEP 658 zusammen implementiert. Dies würde bedeuten, dass Workarounds, die auf implementierungsspezifischen Lösungen beruhen, für jedes Repository, das beides implementiert, repliziert werden müssen, was in allen Fällen nicht einfach oder möglich sein mag (statische Spiegel könnten diese User-Agent-Erkennung z. B. nicht durchführen können).

Nur den JSON-Schlüssel ändern

Der Fehler in pip betrifft nur die JSON-Darstellung der Simple API, so dass wir den Schlüssel tatsächlich nur in JSON ändern *müssen* und die bestehenden HTML-Schlüssel unverändert lassen könnten.

Dieser PEP lehnt dies ab, da wir glauben, dass auf lange Sicht die Abweichung der HTML- und JSON-Schlüsselnamen Fehler wie diesen wahrscheinlicher machen und die Implementierung und das Verständnis der Spezifikation verwirrender machen würden.

Der Hauptgrund, warum wir die HTML-Schlüssel nicht ändern möchten, ist, die PEP 658-Unterstützung in Clients oder Repositories, die nur HTML verwenden und diese bereits unterstützen, nicht zu verlieren. Dieser PEP mindert diesen Bruch, indem er sowohl Clients als auch Servern erlaubt, beide Schlüssel weiterhin zu unterstützen, mit einer Empfehlung, wann und wie dies geschehen sollte.

Empfehlungen

Die Empfehlungen in diesem Abschnitt, abgesehen von diesem Hinweis selbst, sind nicht verbindlich und stellen dar, was die PEP-Autoren für die besten Standardimplementierungsentscheidungen für etwas halten, das diesen PEP implementiert, aber sie stellen keine Anforderung dar, diese Entscheidungen zu befolgen.

Server

Wir empfehlen, dass Server *nur* die neueren Schlüssel ausgeben, insbesondere für die JSON-Darstellung der Simple API, da der Fehler selbst nur JSON betraf.

Server, die PEP 658 in Clients, die HTML verwenden, unterstützen möchten und dies implementiert haben, können sicher beide Schlüssel *nur* in HTML ausgeben.

Server sollten die alten Schlüssel nicht in JSON ausgeben, es sei denn, sie wissen, dass keine fehlerhaften Versionen von pip auf ihren Server zugreifen werden.

Clients

Wir empfehlen, dass Clients beide Schlüssel für HTML und JSON unterstützen und den neueren Schlüssel bevorzugen, wie dieser PEP vorschreibt. Dies ermöglicht es Clients, Repositories zu unterstützen, die PEP 658 und PEP 691 bereits korrekt implementiert haben, aber diesen PEP noch nicht.


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

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