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

Python Enhancement Proposals

PEP 610 – Erfassung des direkten URL-Ursprungs installierter Distributionen

Autor:
Stéphane Bidoul <stephane.bidoul at gmail.com>, Chris Jerdonek <chris.jerdonek at gmail.com>
Sponsor:
Alyssa Coghlan <ncoghlan at gmail.com>
BDFL-Delegate:
Pradyun Gedam <pradyunsg at gmail.com>
Discussions-To:
Discourse thread
Status:
Final
Typ:
Standards Track
Thema:
Packaging
Erstellt:
21. Apr. 2019
Post-History:

Resolution:
Discourse-Nachricht

Inhaltsverzeichnis

Wichtig

Dieser PEP ist ein historisches Dokument. Die aktuelle, kanonische Spezifikation, Erfassung des direkten URL-Ursprungs installierter Distributionen, wird auf der PyPA Specs-Seite gepflegt.

×

Siehe den PyPA-Spezifikations-Update-Prozess, um Änderungen vorzuschlagen.

Zusammenfassung

Gemäß PEP 440 kann eine Distribution durch einen Namen und entweder eine Version oder eine direkte URL-Referenz identifiziert werden (siehe PEP440 Direct References). Nach der Installation werden der Name und die Version in den Projektmetadaten erfasst, aber derzeit gibt es keine Möglichkeit, Details der URL abzurufen, die verwendet wurde, als die Distribution durch eine direkte URL-Referenz identifiziert wurde.

Dieser Vorschlag definiert zusätzliche Metadaten, die vom Installation-Frontend zur installierten Distribution hinzugefügt werden sollen und den direkten URL-Ursprung für die Verwendung durch Konsumenten erfassen, die die Datenbank der installierten Pakete untersuchen (siehe PEP 376).

Motivation

Die ursprüngliche Motivation dieses PEP war es, Werkzeugen mit einer „freeze“-Operation zu ermöglichen, eine Python-Umgebung wiederherstellbar zu machen, und dies in einem breiteren Spektrum von Situationen.

Insbesondere entstand der PEP aus dem Wunsch, pip issue #609 zu lösen: d. h. das Verhalten von pip freeze im Beisein von Distributionen, die aus direkten URL-Referenzen installiert wurden, zu verbessern. Er folgt einem Thread auf discuss.python.org über den besten Vorgehensweg zur Umsetzung.

Installation aus direkten URL-Referenzen

Python-Installationsprogramme wie pip sind in der Lage, Distributionen aus Paketindizes herunterzuladen und zu installieren. Sie sind auch in der Lage, Quellcode aus Anforderungen herunterzuladen und zu installieren, die willkürliche URLs von Quellarchiven und Versionskontrollsystemen (VCS) -Repositories spezifizieren, wie in PEP440 Direct References standardisiert.

Mit anderen Worten, es gibt zwei relevante Installationsmodi.

  1. das zu installierende Paket ist als Name und Versionsspezifizierer angegeben
In diesem Fall sucht das Installationsprogramm in einem Paketindex (oder optional über --find-links im Fall von pip), um die zu installierende Distribution zu finden.
  1. Das zu installierende Paket ist als direkte URL-Referenz angegeben
In diesem Fall lädt das Installationsprogramm herunter, was durch die URL angegeben wird (typischerweise ein Wheel, ein Quellarchiv oder ein VCS-Repository), und installiert es.

In diesem Modus laden Installationsprogramme typischerweise den Quellcode in ein temporäres Verzeichnis herunter, rufen das PEP 517 Build-Backend auf, um bei Bedarf ein Wheel zu erzeugen, installieren das Wheel und löschen das temporäre Verzeichnis.

Nach der Installation bleibt keine Spur der URL, die der Benutzer zum Herunterladen des Pakets angefordert hat, auf dem System des Benutzers zurück.

Einfrieren einer Umgebung

Pip bietet auch einen Befehl namens pip freeze, der die Datenbank der installierten Python-Distributionen untersucht, um eine Liste von Anforderungen zu generieren. Das Hauptziel dieses Befehls ist es, Benutzern zu helfen, eine Liste von Anforderungen zu generieren, die später die Wiederinstallation derselben Umgebung mit höchstmöglicher Genauigkeit ermöglichen.

Ab pip Version 19.3 gibt der Befehl pip freeze für jede installierte Distribution eine Zeile name==version aus (außer bei editierbaren Installationen). Um das Ziel der Wiederinstallation derselben Umgebung zu erreichen, muss das (Name, Version)-Tupel auf eine unveränderliche Version der Distribution verweisen. Die Unveränderlichkeit wird durch Paketindizes wie Warehouse garantiert. Der zu verwendende Paketindex ist typischerweise aus Umgebungs- oder Befehlszeilenparametern des Installationsprogramms bekannt.

Dieser Freeze-Mechanismus funktioniert daher gut für Installationsmodus 1 (d.h. wenn das zu installierende Paket als Name plus Versionsspezifizierer angegeben wurde).

Für Installationsmodus 2, d.h. wenn das zu installierende Paket als direkte URL-Referenz angegeben wurde, ist das Tupel name==version offensichtlich nicht ausreichend, um dieselbe Distribution wiederzuinstallieren, und Benutzer des freeze-Befehls erwarten, dass er die ursprünglich angeforderte URL ausgibt.

Die obige Argumentation ist gleichermaßen anwendbar auf Werkzeuge, die nicht pip freeze sind, und die versuchen würden, ein Pipfile.lock oder ein anderes ähnliches Format aus der Datenbank der installierten Python-Distributionen zu generieren. Sofern nicht anders angegeben, wird „freeze“ in diesem Dokument als allgemeiner Begriff für eine solche Operation verwendet.

Die Bedeutung der Installation aus (VCS-)URLs für Anwendungsintegratoren

Für einen Anwendungsintegrator ist es wichtig, unreleased Versionen von Python-Distributionen zuverlässig installieren und einfrieren zu können. Wenn ein Entwickler beispielsweise eine unveröffentlichte, gepatchte Version einer Abhängigkeit bereitstellen muss, ist es üblich, die Abhängigkeit direkt aus einem VCS-Branch zu installieren, der den Patch enthält, während auf die Veröffentlichung einer aktualisierten Version durch den Maintainer gewartet wird.

In solchen Fällen ist es wichtig, dass „freeze“ die genaue VCS-Referenz (Commit-Hash, falls verfügbar) anpinnt, die installiert wurde, um reproduzierbare Builds mit höchstmöglicher Genauigkeit zu erstellen.

Zusätzliche Ursprungsmetadaten für VCS-URLs

Für VCS-URLs stehen zusätzliche Ursprungsinformationen zur Verfügung, die nur zur Installationszeit nützlich für die Introspektion und bestimmte Arbeitsabläufe sind. Wenn beispielsweise eine Revision aus einer VCS-URL installiert wird, kann ein Werkzeug feststellen, ob die Revision einem Branch, einem Tag oder (im Fall von Git) einem Ref entspricht. Diese Informationen können bei der Introspektion der Datenbank der installierten Distributionen verwendet werden, um Benutzern mehr Informationen darüber zu geben, welche Version installiert wurde (z. B. ob ein Branch oder Tag installiert wurde und, falls ja, den Namen des Branches oder Tags). Dies ermöglicht es auch zu wissen, ob eine PEP 440 direkte Referenz-URL mit der Tag-Form konstruiert werden kann, da nur Tags die Semantik der Unveränderlichkeit haben.

In Fällen, in denen die Revision veränderlich ist (z. B. Branches und Git-Refs), ermöglicht die Kenntnis dieser Informationen Arbeitsabläufe, bei denen Benutzer z. B. auf die neueste Version eines von ihnen verfolgten Branches aktualisieren oder auf die neueste Version eines lokal überprüften Pull-Requests aktualisieren können. Im Gegensatz dazu können Werkzeuge im Voraus (z. B. ohne Netzwerkaufrufe) wissen, dass keine Aktualisierung erforderlich ist, wenn die Revision ein Tag ist.

Wie bei der URL selbst, wenn diese Informationen nicht zur Installationszeit aufgezeichnet werden, wenn das VCS-Repository verfügbar ist, gingen sie sonst verloren.

Hinweis zu „editable“ Installationen

Der Editier-Installationsmodus von pip ermöglicht es einem Benutzer grob, ein lokales Verzeichnis zu sys.path für Entwicklungszwecke einzufügen. Dieser Modus wird etwas missbraucht, um die Tatsache zu umgehen, dass eine nicht-editierbare Installation aus einer VCS-URL den Ursprung nach der Installation verliert. Tatsächlich erfassen editierbare Installationen implizit den VCS-Ursprung im Checkout-Verzeichnis, sodass die Informationen bei der Ausführung von „freeze“ wiederhergestellt werden können.

Die Verwendung dieses Workarounds ist zwar nützlich, aber fragil, schafft Verwirrung über den Zweck des Editier-Modus und funktioniert nur, wenn die Distribution mit setuptools installiert werden kann (d. h. sie ist nicht mit anderen PEP 517 Build-Backends verwendbar).

Wenn dieser PEP implementiert ist, wird es nicht mehr notwendig sein, editierbare Installationen zu verwenden, damit pip freeze korrekt mit VCS-Referenzen funktioniert.

Begründung

Dieser PEP spezifiziert eine neue Metadaten-Datei direct_url.json im Verzeichnis .dist-info einer installierten Distribution.

Die spezifizierten Felder sind ausreichend, um das Quellarchiv und die von pip unterstützten VCS-URLs zu reproduzieren. Sie sind auch ausreichend, um PEP440 Direct References sowie Pipfile und Pipfile.lock-Einträge zu reproduzieren. Schließlich reichen sie aus, um den Branch-, Tag- und/oder Git-Ref-Ursprung der installierten Version aufzuzeichnen, der dank eines vorhandenen VCS-Checkouts bereits für editierbare Installationen verfügbar ist.

Da es bereits mindestens drei verschiedene Möglichkeiten gibt, diese Art von Informationen zu kodieren, verwendet dieser PEP ein Dictionary-Format, um keine Annahmen darüber zu treffen, wie eine direkte URL-Referenz letztendlich in einer Anforderung oder einer Lockdatei kodiert werden muss. Siehe auch den Abschnitt Alternativen unten für weitere Diskussionen über diese Wahl.

Informationen wurden aus dem Handbuch von Rubys Bundler übernommen, um zu überprüfen, ob es ähnliche Fähigkeiten hat und um die Auswahl und Benennung von Feldern in diesen Spezifikationen zu informieren.

Das JSON-Format erlaubt die Hinzufügung zusätzlicher Felder in der Zukunft.

Spezifikation

Dieser PEP spezifiziert eine Datei direct_url.json im Verzeichnis .dist-info einer installierten Distribution, um den direkten URL-Ursprung der Distribution aufzuzeichnen.

Die kanonische Quelle für den Namen und die Semantik dieser Metadatendatei ist das Dokument Erfassung des direkten URL-Ursprungs installierter Distributionen.

Diese Datei MUSS von Installationsprogrammen erstellt werden, wenn eine Distribution aus einer Anforderung installiert wird, die eine direkte URL-Referenz (einschließlich einer VCS-URL) spezifiziert.

Diese Datei darf NICHT erstellt werden, wenn eine Distribution aus einer anderen Art von Anforderung installiert wird (d. h. Name plus Versionsspezifizierer).

Diese JSON-Datei MUSS ein Dictionary sein, konform mit RFC 8259 und UTF-8-kodiert.

Falls vorhanden, MUSS sie mindestens zwei Felder enthalten. Das erste Feld ist url vom Typ string. Abhängig davon, worauf sich url bezieht, MUSS das zweite Feld eines von vcs_info (wenn url eine VCS-Referenz ist), archive_info (wenn url ein Quellarchiv oder ein Wheel ist) oder dir_info (wenn url ein lokales Verzeichnis ist) sein. Diese Info-Felder haben ein (möglicherweise leeres) Subdictionary als Wert, mit den unten definierten möglichen Schlüsseln.

url MUSS aus Sicherheitsgründen von allen sensiblen Authentifizierungsinformationen bereinigt werden.

Der Benutzer:Passwort-Teil der URL KANN jedoch aus Umgebungsvariablen bestehen, die dem folgenden regulären Ausdruck entsprechen

\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?

Zusätzlich KANN der Benutzer:Passwort-Teil der URL eine bekannte, nicht sicherheitsrelevante Zeichenkette sein. Ein typisches Beispiel ist git im Falle einer URL wie ssh://git@gitlab.com.

Wenn url sich auf ein VCS-Repository bezieht, MUSS der Schlüssel vcs_info als Dictionary mit den folgenden Schlüsseln vorhanden sein

  • Ein Schlüssel vcs (Typ string) MUSS vorhanden sein und den Namen des VCS enthalten (d. h. eines von git, hg, bzr, svn). Andere VCS’s SOLLTEN registriert werden, indem ein PEP geschrieben wird, um diese Spezifikation zu ergänzen. Der Wert von url MUSS mit dem entsprechenden VCS kompatibel sein, sodass ein Installationsprogramm ihn ohne Transformation an einen Checkout/Download-Befehl des VCS übergeben kann.
  • Ein Schlüssel requested_revision (Typ string) KANN vorhanden sein und einen Branch/Tag/Ref/Commit/Revision/etc. (in einem für das VCS kompatiblen Format) zum Installieren benennen.
  • Ein Schlüssel commit_id (Typ string) MUSS vorhanden sein und die exakte Commit/Revision-Nummer enthalten, die installiert wurde. Wenn das VCS Commit-Hash-basierte Revisionsbezeichner unterstützt, MUSS ein solcher Commit-Hash als commit_id verwendet werden, um die unveränderliche Version des installierten Quellcodes zu referenzieren.
  • Wenn das Installationsprogramm zusätzliche Informationen über die angeforderte Revision ermitteln konnte, KANN es ein Feld resolved_revision und/oder resolved_revision_type hinzufügen. Wenn in der angeforderten URL keine Revision angegeben wurde, KANN resolved_revision den installierten Standard-Branch enthalten und resolved_revision_type wird branch sein. Wenn das Installationsprogramm feststellt, dass requested_revision ein Tag war, KANN es resolved_revision_type mit dem Wert tag hinzufügen.

Wenn url sich auf ein Quellarchiv oder ein Wheel bezieht, MUSS der Schlüssel archive_info als Dictionary mit dem folgenden Schlüssel vorhanden sein

  • Ein Schlüssel hash (Typ string) SOLLTE vorhanden sein, mit dem Wert <hash-algorithm>=<expected-hash>. Es wird EMPOHLEN, nur Hashes zu verwenden, die bedingungslos von der neuesten Version des hashlib-Moduls der Standardbibliothek bereitgestellt werden, für Quellarchiv-Hashes. Zum Zeitpunkt der Erstellung besteht diese Liste aus „md5“, „sha1“, „sha224“, „sha256“, „sha384“ und „sha512“.

Wenn url sich auf ein lokales Verzeichnis bezieht, MUSS der Schlüssel dir_info als Dictionary mit dem folgenden Schlüssel vorhanden sein

  • editable (Typ: boolean): true, wenn die Distribution im Editier-Modus installiert wurde, andernfalls false. Wenn abwesend, Standard ist false.

Wenn url sich auf ein lokales Verzeichnis bezieht, MUSS es das Schema file haben und konform mit RFC 8089 sein. Insbesondere muss der Pfadkomponente absolut sein. Symbolische Links SOLLTEN bei der Umwandlung von relativen Pfaden in absolute beibehalten werden.

Hinweis

Wenn die angeforderte URL das Schema file:// hat und auf ein lokales Verzeichnis zeigt, das zufällig ein VCS-Checkout enthält, DÜRFEN Installationsprogramme nicht versuchen, VCS-Informationen abzuleiten und daher KEINE VCS-bezogenen Informationen (wie vcs_info) in direct_url.json ausgeben.

Ein Top-Level-Feld subdirectory KANN vorhanden sein, das einen Verzeichnispfad enthält, relativ zum Stamm des VCS-Repositories, Quellarchivs oder lokalen Verzeichnisses, um anzugeben, wo sich pyproject.toml oder setup.py befindet.

Hinweis

Als allgemeine Regel sollten Installationsprogramme die Informationen, die in der angeforderten URL bereitgestellt wurden, so weit wie möglich beibehalten, wenn sie direct_url.json generieren. Zum Beispiel sollten Benutzer:Passwort-Umgebungsvariablen beibehalten werden und requested_revision sollte die in der angeforderten URL bereitgestellte Revision so getreu wie möglich widerspiegeln. Diese Informationen werden jedoch mit präziseren Daten *angereichert*, wie z. B. commit_id.

Registrierte VCS

Dieser Abschnitt listet die registrierten VCS auf; erweiterte, VCS-spezifische Informationen zur Verwendung der Felder vcs, requested_revision und anderer Felder von vcs_info; und in einigen Fällen zusätzliche VCS-spezifische Felder. Werkzeuge KÖNNEN andere VCS unterstützen, obwohl es EMPOHLEN wird, sie zu registrieren, indem ein PEP zur Ergänzung dieser Spezifikation geschrieben wird. Das Feld vcs SOLLTE der Befehlsname (kleingeschrieben) sein. Zusätzliche Felder, die zur Unterstützung solcher VCS notwendig wären, SOLLTEN mit dem VCS-Befehlsnamen präfixiert werden.

Git

Homepage

VCS-Befehl

git

Feld vcs

git

Feld requested_revision

Ein Tag-Name, ein Branch-Name, ein Git-Ref, ein Commit-Hash, ein verkürzter Commit-Hash oder ein anderer Commit-ähnlicher Ausdruck.

Feld commit_id

Ein Commit-Hash (40 hexadezimale Zeichen sha1).

Hinweis

Installationsprogramme können die Befehle git show-ref und git symbolic-ref verwenden, um festzustellen, ob die requested_revision einem Git-Ref entspricht. Ein Ref, der mit refs/tags/ beginnt, entspricht einem Tag, und ein Ref, der nach dem Klonen mit refs/remotes/origin/ beginnt, entspricht einem Branch.

Mercurial

Homepage

VCS-Befehl

hg

Feld vcs

hg

Feld requested_revision

Ein Tag-Name, ein Branch-Name, eine Changeset-ID, eine verkürzte Changeset-ID.

Feld commit_id

Eine Changeset-ID (40 hexadezimale Zeichen).

Bazaar

Homepage

VCS-Befehl

bzr

Feld vcs

bzr

Feld requested_revision

Ein Tag-Name, ein Branch-Name, eine Revisions-ID.

Feld commit_id

Eine Revisions-ID.

Subversion

Homepage

VCS-Befehl

svn

Feld vcs

svn

Feld requested_revision

requested_revision muss mit der Option svn checkout --revision kompatibel sein. In Subversion ist der Branch oder Tag Teil der url.

Feld commit_id

Da Subversion keine global eindeutigen Identifikatoren unterstützt, ist dieses Feld die Subversion-Revisionsnummer im entsprechenden Repository.

Beispiele

Beispiel direct_url.json

Quellarchiv

{
    "url": "https://github.com/pypa/pip/archive/1.3.1.zip",
    "archive_info": {
        "hash": "sha256=2dc6b5a470a1bde68946f263f1af1515a2574a150a30d6ce02c6ff742fcc0db8"
    }
}

Git-URL mit Tag und Commit-Hash

{
    "url": "https://github.com/pypa/pip.git",
    "vcs_info": {
        "vcs": "git",
        "requested_revision": "1.3.1",
        "resolved_revision_type": "tag",
        "commit_id": "7921be1537eac1e97bc40179a57f0349c2aee67d"
    }
}

Lokales Verzeichnis

{
    "url": "file:///home/user/project",
    "dir_info": {}
}

Lokales Verzeichnis, im Editier-Modus installiert

{
    "url": "file:///home/user/project",
    "dir_info": {
        "editable": true
    }
}

Beispiel pip-Befehle und ihre Auswirkung auf direct_url.json

Befehle, die eine direct_url.json generieren

  • pip install https://example.com/app-1.0.tgz
  • pip install https://example.com/app-1.0.whl
  • pip install „git+https://example.com/repo/app.git#egg=app&subdirectory=setup“
  • pip install ./app
  • pip install file:///home/user/app
  • pip install –editable „git+https://example.com/repo/app.git#egg=app&subdirectory=setup“ (in diesem Fall ist url das lokale Verzeichnis, in das das Git-Repository geklont wurde, und dir_info wird mit "editable": true vorhanden sein, und keine vcs_info wird gesetzt)
  • pip install -e ./app

Befehle, die *keine* direct_url.json generieren

Anwendungsfälle

Umgebung „einfrieren“

Werkzeuge wie pip freeze, die Anforderungen aus der Datenbank der installierten Python-Distributionen generieren, SOLLTEN direct_url.json nutzen, wenn es vorhanden ist, und ihm Vorrang vor den Versionsmetadaten geben, um eine Ausgabe mit höherer Genauigkeit zu generieren. Im Beisein einer direkten URL-Referenz vom Typ vcs SOLLTE das Feld commit_id vorrangig verwendet werden, um die höchstmögliche Genauigkeit für die ursprünglich installierte Version zu gewährleisten. Wenn es von ihrem Anforderungsformat unterstützt wird, werden Werkzeuge ermutigt, auch den Wert tag auszugeben, falls vorhanden, da dieser unveränderliche Semantik hat. Werkzeuge KÖNNEN einen anderen Ansatz wählen, abhängig von den Bedürfnissen ihrer Benutzer.

Beachten Sie, dass die anfängliche Iteration dieses PEP nicht versucht, Umgebungen, die editierbare Installationen oder Installationen aus lokalen Verzeichnissen enthalten, reproduzierbar zu machen, aber sie versucht, sie leicht identifizierbar zu machen. Durch die Lokalisierung des lokalen Projektverzeichnisses über die Felder url und dir_info dieser Spezifikation können Werkzeuge jede Strategie implementieren, die zu ihren Anwendungsfällen passt.

Abwärtskompatibilität

Da dieser PEP eine neue Datei im Verzeichnis .dist-info spezifiziert, gibt es keine Abwärtskompatibilitätsprobleme.

Alternativen

PEP 426 source_url

Der nun zurückgezogene PEP 426 spezifiziert einen Metadateneintrag source_url. Er ist auch in distlib implementiert.

Er war für einen leicht anderen Zweck bestimmt, für die Verwendung in sdists.

Dieses Format unterstützt nicht die Option subdirectory von pip-Anforderungs-URLs. Die gleiche Einschränkung besteht bei PEP440 Direct References.

Es fehlt auch die explizite Unterstützung für Umgebungsvariablen im Benutzer:Passwort-Teil von URLs.

Die Einführung eines Schlüssel/Wert-Erweiterungsmechanismus und die Unterstützung von Umgebungsvariablen für Benutzer:Passwort in PEP 440 wären für die Verwendung in diesem PEP notwendig.

Revision vs. Ref

Der Schlüssel requested_revision wurde gegenüber requested_ref beibehalten, da er ein allgemeinerer Begriff für verschiedene VCS ist und ref eine spezifische Bedeutung für git hat.

Danksagungen

Verschiedene Personen haben dazu beigetragen, diesen PEP zu realisieren. Paul F. Moore lieferte die Essenz des Abstracts. Alyssa Coghlan schlug den Namen direct_url vor.


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

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