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
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.
- das zu installierende Paket ist als Name und Versionsspezifizierer angegeben
In diesem Fall sucht das Installationsprogramm in einem Paketindex (oder optional über--find-linksim Fall von pip), um die zu installierende Distribution zu finden.
- 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(Typstring) MUSS vorhanden sein und den Namen des VCS enthalten (d. h. eines vongit,hg,bzr,svn). Andere VCS’s SOLLTEN registriert werden, indem ein PEP geschrieben wird, um diese Spezifikation zu ergänzen. Der Wert vonurlMUSS 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(Typstring) 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(Typstring) 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 alscommit_idverwendet 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_revisionund/oderresolved_revision_typehinzufügen. Wenn in der angeforderten URL keine Revision angegeben wurde, KANNresolved_revisionden installierten Standard-Branch enthalten undresolved_revision_typewirdbranchsein. Wenn das Installationsprogramm feststellt, dassrequested_revisionein Tag war, KANN esresolved_revision_typemit dem Werttaghinzufü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(Typstring) SOLLTE vorhanden sein, mit dem Wert<hash-algorithm>=<expected-hash>. Es wird EMPOHLEN, nur Hashes zu verwenden, die bedingungslos von der neuesten Version deshashlib-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, andernfallsfalse. Wenn abwesend, Standard istfalse.
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_revisionmuss mit der Optionsvn checkout--revisionkompatibel sein. In Subversion ist der Branch oder Tag Teil derurl.
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
urldas lokale Verzeichnis, in das das Git-Repository geklont wurde, unddir_infowird mit"editable": truevorhanden sein, und keinevcs_infowird gesetzt) - pip install -e ./app
Befehle, die *keine* direct_url.json generieren
- pip install app
- pip install app –no-index –find-links https://example.com/
Anwendungsfälle
Umgebung „einfrieren“
Werkzeuge wiepip freeze, die Anforderungen aus der Datenbank der installierten Python-Distributionen generieren, SOLLTENdirect_url.jsonnutzen, 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 TypvcsSOLLTE das Feldcommit_idvorrangig 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 Werttagauszugeben, 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
urlunddir_infodieser 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.
Urheberrecht
Dieses Dokument wird in die Public Domain oder unter die CC0-1.0-Universal-Lizenz gestellt, je nachdem, welche Lizenz permissiver ist.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0610.rst
Zuletzt geändert: 2025-02-01 08:55:40 GMT