PEP 440 – Versionserkennung und Abhängigkeitsspezifikation
- Autor:
- Alyssa Coghlan <ncoghlan at gmail.com>, Donald Stufft <donald at stufft.io>
- BDFL-Delegate:
- Alyssa Coghlan <ncoghlan at gmail.com>
- Discussions-To:
- Distutils-SIG Liste
- Status:
- Final
- Typ:
- Standards Track
- Thema:
- Packaging
- Erstellt:
- 18. Mrz. 2013
- Post-History:
- 30. Mrz. 2013, 27. Mai 2013, 20. Jun. 2013, 21. Dez. 2013, 28. Jan. 2014, 08. Aug. 2014, 22. Aug. 2014
- Ersetzt:
- 386
- Resolution:
- Distutils-SIG Nachricht
Inhaltsverzeichnis
- Zusammenfassung
- Definitionen
- Versionsschema
- Öffentliche Versionskennungen
- Lokale Versionskennungen
- Finale Veröffentlichungen
- Vorab-Veröffentlichungen
- Nachveröffentlichungen
- Entwicklungsveröffentlichungen
- Versionsepochen
- Normalisierung
- Groß-/Kleinschreibung
- Ganzzahlige Normalisierung
- Trennsymbole für Vorab-Veröffentlichungen
- Schreibweise von Vorab-Veröffentlichungen
- Implizite Nummer von Vorab-Veröffentlichungen
- Trennsymbole für Nachveröffentlichungen
- Schreibweise von Nachveröffentlichungen
- Implizite Nummer von Nachveröffentlichungen
- Implizite Nachveröffentlichungen
- Trennsymbole für Entwicklungsveröffentlichungen
- Implizite Nummer von Entwicklungsveröffentlichungen
- Lokale Versionssegmente
- Vorausgehendes „v“-Zeichen
- Führende und nachfolgende Leerzeichen
- Beispiele für konforme Versionsschemata
- Zusammenfassung der zulässigen Suffixe und relative Reihenfolge
- Versionsreihenfolge über verschiedene Metadatenversionen hinweg
- Kompatibilität mit anderen Versionsschemata
- Versionsspezifikatoren
- Direkte Referenzen
- Aktualisierung der Versionsspezifikation
- Zusammenfassung der Unterschiede zu pkg_resources.parse_version
- Zusammenfassung der Unterschiede zu PEP 386
- Änderung des Versionsschemas
- Eine meinungsfreundlichere Beschreibung des Versionsschemas
- Beschreibung von Versionsspezifikatoren neben dem Versionsschema
- Änderung der Interpretation von Versionsspezifikatoren
- Unterstützung für datumsbasierte Versionskennungen
- Hinzufügen von Versionsepochen
- Hinzufügen von direkten Referenzen
- Hinzufügen von beliebiger Gleichheit
- Hinzufügen von lokalen Versionskennungen
- Bereitstellung expliziter Versionsnormalisierungsregeln
- Zulassen von Unterstrichen in der Normalisierung
- Zusammenfassung der Änderungen an PEP 440
- Referenzen
- Anhang A
- Anhang B: Parsen von Versionszeichenfolgen mit regulären Ausdrücken
- Urheberrecht
Zusammenfassung
Dieses PEP beschreibt ein Schema zur Identifizierung von Versionen von Python-Softwareverteilungen und zur Deklaration von Abhängigkeiten von bestimmten Versionen.
Dieses Dokument befasst sich mit mehreren Einschränkungen des früheren Versuchs einer standardisierten Herangehensweise an die Versionierung, wie sie in PEP 345 und PEP 386 beschrieben sind.
Definitionen
Die Schlüsselwörter „MUSS“, „DARF NICHT“, „ERFORDERLICH“, „SOLL“, „SOLL NICHT“, „EMPFOHLEN“, „KANN“ und „OPTIONAL“ in diesem Dokument sind wie in RFC 2119 beschrieben zu interpretieren.
„Projekte“ sind Softwarekomponenten, die zur Integration bereitgestellt werden. Projekte umfassen Python-Bibliotheken, Frameworks, Skripte, Plugins, Anwendungen, Datensammlungen oder andere Ressourcen und verschiedene Kombinationen davon. Öffentliche Python-Projekte werden typischerweise im Python Package Index registriert.
„Veröffentlichungen“ sind eindeutig identifizierte Schnappschüsse eines Projekts.
„Distributionen“ sind die gepackten Dateien, die zur Veröffentlichung und Verteilung einer Veröffentlichung verwendet werden.
„Build-Tools“ sind automatisierte Werkzeuge, die auf Entwicklungssystemen ausgeführt werden und Quell- und Binärdistributionsarchive erstellen. Build-Tools können auch von Integrationswerkzeugen aufgerufen werden, um Software zu erstellen, die als sdists anstelle von vorab kompilierten Binärarchiven verteilt wird.
„Index-Server“ sind aktive Distributionsregister, die Versions- und Abhängigkeitsmetadaten veröffentlichen und Einschränkungen für zulässige Metadaten festlegen.
„Publication Tools“ sind automatisierte Werkzeuge, die auf Entwicklungssystemen ausgeführt werden und Quell- und Binärdistributionsarchive auf Index-Server hochladen.
„Installation Tools“ sind Integrationswerkzeuge, die speziell auf Zielsystemen ausgeführt werden, Quell- und Binärdistributionsarchive von einem Index-Server oder einem anderen angegebenen Speicherort konsumieren und diese auf dem Zielsystem bereitstellen.
„Automatisierte Werkzeuge“ ist ein Sammelbegriff, der Build-Tools, Index-Server, Publication Tools, Integration Tools und jede andere Software umfasst, die Distributionsversions- und Abhängigkeitsmetadaten erstellt oder konsumiert.
Versionsschema
Distributionen werden durch eine öffentliche Versionskennung identifiziert, die alle definierten Versionsvergleichsoperationen unterstützt
Das Versionsschema wird sowohl verwendet, um die von einem bestimmten Distributionsarchiv bereitgestellte Distributionsversion zu beschreiben, als auch um Einschränkungen für die Version von Abhängigkeiten festzulegen, die zum Erstellen oder Ausführen der Software benötigt werden.
Öffentliche Versionskennungen
Die kanonischen öffentlichen Versionskennungen MÜSSEN dem folgenden Schema entsprechen
[N!]N(.N)*[{a|b|rc}N][.postN][.devN]
Öffentliche Versionskennungen DÜRFEN KEINE führenden oder nachfolgenden Leerzeichen enthalten.
Öffentliche Versionskennungen MÜSSEN innerhalb einer gegebenen Distribution eindeutig sein.
Installation Tools SOLLTEN alle öffentlichen Versionen ignorieren, die diesem Schema nicht entsprechen, MÜSSEN aber auch die unten angegebenen Normalisierungen einschließen. Installation Tools KÖNNEN den Benutzer warnen, wenn nicht konforme oder mehrdeutige Versionen erkannt werden.
Siehe auch Anhang B : Parsen von Versionszeichenfolgen mit regulären Ausdrücken, das einen regulären Ausdruck zur Prüfung der strikten Konformität mit dem kanonischen Format sowie einen permissiveren regulären Ausdruck, der Eingaben akzeptiert, die eine anschließende Normalisierung erfordern können, bereitstellt.
Öffentliche Versionskennungen werden in bis zu fünf Segmente unterteilt
- Epoch-Segment:
N! - Release-Segment:
N(.N)* - Vorab-Release-Segment:
{a|b|rc}N - Nachveröffentlichungs-Segment:
.postN - Entwicklungs-Release-Segment:
.devN
Jede gegebene Veröffentlichung ist eine „finale Veröffentlichung“, „Vorab-Veröffentlichung“, „Nachveröffentlichung“ oder „Entwicklungsveröffentlichung“, wie in den folgenden Abschnitten definiert.
Alle numerischen Komponenten MÜSSEN nicht-negative Ganzzahlen sein, die als Sequenzen von ASCII-Ziffern dargestellt werden.
Alle numerischen Komponenten MÜSSEN nach ihrem numerischen Wert und nicht als Textzeichenfolgen interpretiert und sortiert werden.
Alle numerischen Komponenten KÖNNEN Null sein. Mit Ausnahme der unten für das Release-Segment beschriebenen Fälle hat eine numerische Komponente von Null keine besondere Bedeutung, außer dass sie immer der niedrigste mögliche Wert in der Versionsreihenfolge ist.
Hinweis
Einige schwer lesbare Versionskennungen sind durch dieses Schema zulässig, um die große Bandbreite der Versionspraktiken in bestehenden öffentlichen und privaten Python-Projekten besser zu berücksichtigen.
Folglich werden einige der Versionspraktiken, die technisch durch das PEP zulässig sind, für neue Projekte dringend abgeraten. Wo dies der Fall ist, werden die relevanten Details in den folgenden Abschnitten vermerkt.
Lokale Versionskennungen
Lokale Versionskennungen MÜSSEN dem folgenden Schema entsprechen
<public version identifier>[+<local version label>]
Sie bestehen aus einer normalen öffentlichen Versionskennung (wie im vorherigen Abschnitt definiert) zusammen mit einem beliebigen „lokalen Versions-Label“, getrennt von der öffentlichen Versionskennung durch ein Pluszeichen. Lokale Versions-Labels haben keine spezifische Semantik, aber es werden einige syntaktische Einschränkungen auferlegt.
Lokale Versionskennungen werden verwendet, um vollständig API- (und ggf. ABI-) kompatible gepatchte Versionen von Upstream-Projekten zu bezeichnen. Zum Beispiel können diese von Anwendungsentwicklern und Systemintegratoren durch Anwendung spezifischer zurückportierter Fehlerbehebungen erstellt werden, wenn ein Upgrade auf eine neue Upstream-Version zu störend für die Anwendung oder das andere integrierte System (wie eine Linux-Distribution) wäre.
Die Einbeziehung des lokalen Versions-Labels ermöglicht es, Upstream-Veröffentlichungen von potenziell geänderten Neukompilierungen durch Downstream-Integratoren zu unterscheiden. Die Verwendung einer lokalen Versionskennung hat keinen Einfluss auf die Art einer Veröffentlichung, aber wenn sie auf eine Quellverteilung angewendet wird, zeigt sie an, dass sie möglicherweise nicht genau denselben Code wie die entsprechende Upstream-Veröffentlichung enthält.
Um sicherzustellen, dass lokale Versionskennungen leicht als Teil von Dateinamen und URLs aufgenommen werden können und um Formatierungskonsistenz in hexadezimalen Hash-Darstellungen zu vermeiden, MÜSSEN lokale Versions-Labels auf die folgende Menge von zulässigen Zeichen beschränkt sein
- ASCII-Buchstaben (
[a-zA-Z]) - ASCII-Ziffern (
[0-9]) - Punkte (
.)
Lokale Versions-Labels MÜSSEN mit einem ASCII-Buchstaben oder einer Ziffer beginnen und enden.
Der Vergleich und die Sortierung lokaler Versionen berücksichtigen jedes Segment des lokalen Versions-Labels (geteilt durch einen Punkt .) separat. Wenn ein Segment ausschließlich aus ASCII-Ziffern besteht, wird dieser Abschnitt für Vergleichszwecke als Ganzzahl betrachtet. Wenn ein Segment ASCII-Buchstaben enthält, wird dieses Segment lexikografisch und unabhängig von der Groß-/Kleinschreibung verglichen. Beim Vergleich eines numerischen und eines lexikografischen Segments ist das numerische Segment immer größer als das lexikografische Segment. Darüber hinaus ist eine lokale Version mit einer größeren Anzahl von Segmenten immer größer als eine lokale Version mit weniger Segmenten, solange die kürzeren lokalen Versionssegmente exakt mit dem Anfang der längeren lokalen Versionssegmente übereinstimmen.
Ein „Upstream-Projekt“ ist ein Projekt, das seine eigenen öffentlichen Versionen definiert. Ein „Downstream-Projekt“ ist eines, das ein Upstream-Projekt verfolgt und neu verteilt und möglicherweise Sicherheits- und Fehlerkorrekturen aus späteren Versionen des Upstream-Projekts zurückportiert.
Lokale Versionskennungen SOLLTEN nicht bei der Veröffentlichung von Upstream-Projekten auf einem öffentlichen Index-Server verwendet werden, KÖNNEN aber zur Identifizierung privater Builds verwendet werden, die direkt aus dem Quellcode des Projekts erstellt wurden. Lokale Versionskennungen SOLLTEN von Downstream-Projekten verwendet werden, wenn eine Version veröffentlicht wird, die API-kompatibel mit der Version des Upstream-Projekts ist, die durch die öffentliche Versionskennung identifiziert wird, aber zusätzliche Änderungen (wie Fehlerbehebungen) enthält. Da der Python Package Index ausschließlich für die Indizierung und das Hosting von Upstream-Projekten bestimmt ist, DARF er die Verwendung lokaler Versionskennungen NICHT zulassen.
Quellverteilungen, die eine lokale Versionskennung verwenden, SOLLTEN die Erweiterungsmetadaten python.integrator (wie in PEP 459 definiert) bereitstellen.
Finale Veröffentlichungen
Eine Versionskennung, die ausschließlich aus einem Release-Segment und optional einer Epoch-Kennung besteht, wird als „finale Veröffentlichung“ bezeichnet.
Das Release-Segment besteht aus einem oder mehreren nicht-negativen ganzzahligen Werten, die durch Punkte getrennt sind
N(.N)*
Finale Veröffentlichungen innerhalb eines Projekts MÜSSEN in einer konsistent steigenden Reihenfolge nummeriert werden, andernfalls können automatisierte Werkzeuge sie nicht korrekt aktualisieren.
Der Vergleich und die Sortierung von Release-Segmenten berücksichtigen der Reihe nach den numerischen Wert jeder Komponente des Release-Segments. Beim Vergleichen von Release-Segmenten mit unterschiedlicher Anzahl von Komponenten wird das kürzere Segment nach Bedarf mit zusätzlichen Nullen aufgefüllt.
Obwohl unter diesem Schema eine beliebige Anzahl von zusätzlichen Komponenten nach der ersten zulässig ist, sind die gängigsten Varianten die Verwendung von zwei Komponenten („major.minor“) oder drei Komponenten („major.minor.micro“).
Zum Beispiel:
0.9
0.9.1
0.9.2
...
0.9.10
0.9.11
1.0
1.0.1
1.1
2.0
2.0.1
...
Eine Release-Serie ist jede Menge von finalen Release-Nummern, die mit einem gemeinsamen Präfix beginnen. Zum Beispiel sind 3.3.1, 3.3.5 und 3.3.9.45 alle Teil der 3.3-Release-Serie.
Hinweis
X.Y und X.Y.0 werden nicht als unterschiedliche Release-Nummern betrachtet, da die Regeln für den Vergleich von Release-Segmenten die Zwei-Komponenten-Form implizit zu X.Y.0 erweitern, wenn sie mit einem Release-Segment verglichen wird, das drei Komponenten enthält.
Datumsbasierte Release-Segmente sind ebenfalls zulässig. Ein Beispiel für ein datumsbasiertes Release-Schema, das Jahr und Monat der Veröffentlichung verwendet
2012.4
2012.7
2012.10
2013.1
2013.6
...
Vorab-Veröffentlichungen
Einige Projekte verwenden einen „Alpha-, Beta-, Release-Candidate“-Vorab-Release-Zyklus, um die Tests durch ihre Benutzer vor einer finalen Veröffentlichung zu unterstützen.
Wenn diese Vorab-Veröffentlichungen als Teil des Entwicklungszyklus eines Projekts verwendet werden, werden sie durch die Einbeziehung eines Vorab-Release-Segments in die Versionskennung angezeigt
X.YaN # Alpha release
X.YbN # Beta release
X.YrcN # Release Candidate
X.Y # Final release
Eine Versionskennung, die ausschließlich aus einem Release-Segment und einem Vorab-Release-Segment besteht, wird als „Vorab-Veröffentlichung“ bezeichnet.
Das Vorab-Release-Segment besteht aus einer alphabetischen Kennung für die Vorab-Release-Phase zusammen mit einem nicht-negativen ganzzahligen Wert. Vorab-Veröffentlichungen für eine gegebene Veröffentlichung werden zuerst nach Phase (Alpha, Beta, Release Candidate) und dann nach der numerischen Komponente innerhalb dieser Phase geordnet.
Installation Tools KÖNNEN sowohl c als auch rc-Veröffentlichungen für ein gemeinsames Release-Segment akzeptieren, um einige bestehende Legacy-Distributionen zu handhaben.
Installation Tools SOLLTEN c-Versionen als äquivalent zu rc-Versionen interpretieren (d. h. c1 bezeichnet dieselbe Version wie rc1).
Build-Tools, Publication Tools und Index-Server SOLLTEN die Erstellung sowohl von rc- als auch von c-Veröffentlichungen für ein gemeinsames Release-Segment verbieten.
Nachveröffentlichungen
Einige Projekte verwenden Nachveröffentlichungen, um kleinere Fehler in einer finalen Veröffentlichung zu beheben, die die verteilte Software nicht beeinflussen (z. B. die Korrektur eines Fehlers in den Release Notes).
Wenn diese Nachveröffentlichungen als Teil des Entwicklungszyklus eines Projekts verwendet werden, werden sie durch die Einbeziehung eines Nachveröffentlichungs-Segments in die Versionskennung angezeigt
X.Y.postN # Post-release
Eine Versionskennung, die ein Nachveröffentlichungs-Segment ohne ein Entwicklungs-Release-Segment enthält, wird als „Nachveröffentlichung“ bezeichnet.
Das Nachveröffentlichungs-Segment besteht aus der Zeichenkette .post, gefolgt von einem nicht-negativen ganzzahligen Wert. Nachveröffentlichungen werden nach ihrer numerischen Komponente geordnet, unmittelbar nach der entsprechenden Veröffentlichung und vor jeder nachfolgenden Veröffentlichung.
Hinweis
Die Verwendung von Nachveröffentlichungen zur Veröffentlichung von Wartungsversionen, die tatsächliche Fehlerkorrekturen enthalten, wird dringend abgeraten. Im Allgemeinen ist es besser, eine längere Release-Nummer zu verwenden und die finale Komponente für jede Wartungsversion zu erhöhen.
Nachveröffentlichungen sind auch für Vorab-Veröffentlichungen zulässig
X.YaN.postM # Post-release of an alpha release
X.YbN.postM # Post-release of a beta release
X.YrcN.postM # Post-release of a release candidate
Hinweis
Die Erstellung von Nachveröffentlichungen von Vorab-Veröffentlichungen wird dringend abgeraten, da sie die Versionskennung für menschliche Leser schwer lesbar macht. Im Allgemeinen ist es erheblich klarer, einfach eine neue Vorab-Veröffentlichung durch Erhöhung der numerischen Komponente zu erstellen.
Entwicklungsveröffentlichungen
Einige Projekte erstellen regelmäßige Entwicklungsversionen, und Systempaketierer (insbesondere für Linux-Distributionen) möchten möglicherweise frühe Versionen direkt aus der Quellcodeverwaltung erstellen, die nicht mit späteren Projektversionen kollidieren.
Wenn diese Entwicklungsversionen als Teil des Entwicklungszyklus eines Projekts verwendet werden, werden sie durch die Einbeziehung eines Entwicklungs-Release-Segments in die Versionskennung angezeigt
X.Y.devN # Developmental release
Eine Versionskennung, die ein Entwicklungs-Release-Segment enthält, wird als „Entwicklungsversion“ bezeichnet.
Das Entwicklungs-Release-Segment besteht aus der Zeichenkette .dev, gefolgt von einem nicht-negativen ganzzahligen Wert. Entwicklungsversionen werden nach ihrer numerischen Komponente geordnet, unmittelbar vor der entsprechenden Veröffentlichung (und vor allen Vorab-Veröffentlichungen mit demselben Release-Segment) und nach jeder vorherigen Veröffentlichung (einschließlich Nachveröffentlichungen).
Entwicklungsversionen sind auch für Vorab-Veröffentlichungen und Nachveröffentlichungen zulässig
X.YaN.devM # Developmental release of an alpha release
X.YbN.devM # Developmental release of a beta release
X.YrcN.devM # Developmental release of a release candidate
X.Y.postN.devM # Developmental release of a post-release
Hinweis
Obwohl sie für Continuous-Integration-Zwecke nützlich sein mögen, wird die Veröffentlichung von Entwicklungsversionen von Vorab-Veröffentlichungen auf allgemeinen öffentlichen Index-Servern dringend abgeraten, da sie die Versionskennung für menschliche Leser schwer lesbar macht. Wenn eine solche Veröffentlichung veröffentlicht werden muss, ist es erheblich klarer, stattdessen eine neue Vorab-Veröffentlichung durch Erhöhung der numerischen Komponente zu erstellen.
Entwicklungsversionen von Nachveröffentlichungen werden ebenfalls dringend abgeraten, aber sie können für Projekte geeignet sein, die die Nachveröffentlichungs-Notation für vollständige Wartungsversionen verwenden, die Code-Änderungen enthalten können.
Versionsepochen
Wenn eine Epoch in einer Versionskennung enthalten ist, erscheint sie vor allen anderen Komponenten, getrennt vom Release-Segment durch ein Ausrufezeichen
E!X.Y # Version identifier with epoch
Wenn keine explizite Epoch angegeben ist, ist die implizite Epoch 0.
Die meisten Versionskennungen werden keine Epoch enthalten, da eine explizite Epoch nur benötigt wird, wenn ein Projekt die Art und Weise, wie es Versionen nummeriert, *ändert*, sodass die normalen Versionssortierregeln das falsche Ergebnis liefern. Zum Beispiel, wenn ein Projekt datumsbasierte Versionen wie 2014.04 verwendet und zu semantischen Versionen wie 1.0 wechseln möchte, dann werden die neuen Veröffentlichungen als *älter* als die datumsbasierten Veröffentlichungen betrachtet, wenn das normale Sortierschema verwendet wird
1.0
1.1
2.0
2013.10
2014.04
Durch die Angabe einer expliziten Epoch kann die Sortierreihenfolge jedoch entsprechend geändert werden, da alle Versionen aus einer späteren Epoch nach Versionen aus einer früheren Epoch sortiert werden
2013.10
2014.04
1!1.0
1!1.1
1!2.0
Normalisierung
Um eine bessere Kompatibilität mit bestehenden Versionen zu gewährleisten, gibt es eine Reihe von „alternativen“ Syntaxes, die bei der Interpretation von Versionen berücksichtigt werden MÜSSEN. Diese Syntaxes MÜSSEN bei der Interpretation einer Version berücksichtigt werden, sie sollten jedoch in die oben definierte Standard-Syntax „normalisiert“ werden.
Groß-/Kleinschreibung
Alle ASCII-Buchstaben sollten innerhalb einer Version als case-insensitiv interpretiert werden, und die Normalform ist Kleinbuchstaben. Dies ermöglicht Versionen wie 1.1RC1, die zu 1.1rc1 normalisiert werden.
Ganzzahlige Normalisierung
Alle Ganzzahlen werden über die eingebaute Funktion int() interpretiert und zu ihrer String-Darstellung normalisiert. Das bedeutet, dass eine Ganzzahlversion von 00 zu 0 normalisiert wird, während 09000 zu 9000 normalisiert wird. Dies gilt nicht für Ganzzahlen innerhalb eines alphanumerischen Segments einer lokalen Version, wie z. B. 1.0+foo0100, das sich bereits in seiner normalisierten Form befindet.
Trennsymbole für Vorab-Veröffentlichungen
Vorab-Veröffentlichungen sollten einen Trennpunkt ., einen Bindestrich - oder einen Unterstrich _ zwischen dem Release-Segment und dem Vorab-Release-Segment zulassen. Die Normalform hierfür ist ohne Trennzeichen. Dies ermöglicht Versionen wie 1.1.a1 oder 1.1-a1, die zu 1.1a1 normalisiert werden. Es sollte auch ein Trennzeichen zwischen dem Vorab-Release-Signifikator und der Zahl zulässig sein. Dies ermöglicht Versionen wie 1.0a.1, die zu 1.0a1 normalisiert werden.
Schreibweise von Vorab-Veröffentlichungen
Vorab-Veröffentlichungen erlauben die zusätzlichen Schreibweisen alpha, beta, c, pre und preview für a, b, rc, rc und rc. Dies ermöglicht Versionen wie 1.1alpha1, 1.1beta2 oder 1.1c3, die zu 1.1a1, 1.1b2 bzw. 1.1rc3 normalisiert werden. In jedem Fall sollte die zusätzliche Schreibweise als äquivalent zu ihrer Normalform betrachtet werden.
Implizite Nummer von Vorab-Veröffentlichungen
Vorab-Veröffentlichungen erlauben das Weglassen der Zahl, in diesem Fall wird sie implizit als 0 angenommen. Die Normalform hierfür ist, die 0 explizit einzuschließen. Dies ermöglicht Versionen wie 1.2a, die zu 1.2a0 normalisiert werden.
Trennsymbole für Nachveröffentlichungen
Nachveröffentlichungen erlauben einen Trennpunkt ., einen Bindestrich - oder einen Unterstrich _ sowie das Weglassen des Trennzeichens insgesamt. Die Normalform hiervon ist mit dem Trennpunkt .. Dies ermöglicht Versionen wie 1.2-post2 oder 1.2post2, die zu 1.2.post2 normalisiert werden. Wie beim Trennzeichen für Vorab-Veröffentlichungen erlaubt dies auch ein optionales Trennzeichen zwischen dem Nachveröffentlichungs-Signifikator und der Zahl. Dies ermöglicht Versionen wie 1.2.post-2, die zu 1.2.post2 normalisiert werden.
Schreibweise von Nachveröffentlichungen
Nachveröffentlichungen erlauben die zusätzlichen Schreibweisen rev und r. Dies ermöglicht Versionen wie 1.0-r4, die zu 1.0.post4 normalisiert werden. Wie bei den Vorab-Veröffentlichungen sollten die zusätzlichen Schreibweisen als äquivalent zu ihren Normalformen betrachtet werden.
Implizite Nummer von Nachveröffentlichungen
Nachveröffentlichungen erlauben das Weglassen der Zahl, in diesem Fall wird sie implizit als 0 angenommen. Die Normalform hierfür ist, die 0 explizit einzuschließen. Dies ermöglicht Versionen wie 1.2.post, die zu 1.2.post0 normalisiert werden.
Implizite Nachveröffentlichungen
Nachveröffentlichungen erlauben das Weglassen des post-Signifikators insgesamt. Bei Verwendung dieser Form MUSS das Trennzeichen ein Bindestrich - sein und keine andere Form ist zulässig. Dies ermöglicht Versionen wie 1.0-1, die zu 1.0.post1 normalisiert werden. Diese spezielle Normalisierung DARF NICHT in Verbindung mit der Regel der impliziten Nachveröffentlichungsnummer verwendet werden. Mit anderen Worten, 1.0- ist *keine* gültige Version und wird *nicht* zu 1.0.post0 normalisiert.
Trennsymbole für Entwicklungsveröffentlichungen
Entwicklungsversionen erlauben einen Trennpunkt ., einen Bindestrich - oder einen Unterstrich _ sowie das Weglassen des Trennzeichens insgesamt. Die Normalform hierfür ist mit dem Trennpunkt .. Dies ermöglicht Versionen wie 1.2-dev2 oder 1.2dev2, die zu 1.2.dev2 normalisiert werden.
Implizite Nummer von Entwicklungsveröffentlichungen
Entwicklungsversionen erlauben das Weglassen der Zahl, in diesem Fall wird sie implizit als 0 angenommen. Die Normalform hierfür ist, die 0 explizit einzuschließen. Dies ermöglicht Versionen wie 1.2.dev, die zu 1.2.dev0 normalisiert werden.
Lokale Versionssegmente
Bei lokalen Versionen ist neben der Verwendung von . als Trennzeichen für Segmente auch die Verwendung von - und _ zulässig. Die Normalform ist die Verwendung des Punktes .. Dies ermöglicht Versionen wie 1.0+ubuntu-1, die zu 1.0+ubuntu.1 normalisiert werden.
Vorausgehendes „v“-Zeichen
Um die übliche Versionsnotation v1.0 zu unterstützen, können Versionen durch ein einzelnes Literal v vorangestellt werden. Dieses Zeichen MUSS für alle Zwecke ignoriert werden und sollte aus allen normalisierten Formen der Version weggelassen werden. Dieselbe Version mit und ohne das v gilt als äquivalent.
Führende und nachfolgende Leerzeichen
Führende und nachfolgende Leerzeichen müssen stillschweigend ignoriert und aus allen normalisierten Formen einer Version entfernt werden. Dies schließt Leerzeichen " ", Tabulatoren \t, Zeilenumbrüche \n, Wagenrückläufe \r, Seitenvorschübe \f und vertikale Tabulatoren \v ein. Dies ermöglicht eine sinnvolle Handhabung von versehentlichen Leerzeichen, wie z. B. bei einer Version wie 1.0\n, die zu 1.0 normalisiert wird.
Beispiele für konforme Versionsschemata
Das Standard-Versionsschema ist darauf ausgelegt, eine breite Palette von Identifizierungspraktiken in öffentlichen und privaten Python-Projekten abzudecken. In der Praxis würde ein einzelnes Projekt, das versucht, die volle Flexibilität des Schemas zu nutzen, eine Situation schaffen, in der menschliche Benutzer Schwierigkeiten hätten, die relative Reihenfolge der Versionen zu ermitteln, obwohl die oben genannten Regeln sicherstellen, dass alle konformen Werkzeuge sie konsistent sortieren werden.
Die folgenden Beispiele veranschaulichen eine kleine Auswahl der verschiedenen Ansätze, die Projekte zur Identifizierung ihrer Releases wählen können, während gleichzeitig sichergestellt wird, dass die „neueste Version“ und die „neueste stabile Version“ sowohl für menschliche Benutzer als auch für automatisierte Werkzeuge leicht ermittelt werden können.
Einfache „Major.Minor“-Versionsverwaltung
0.1
0.2
0.3
1.0
1.1
...
Einfache „Major.Minor.Micro“-Versionsverwaltung
1.1.0
1.1.1
1.1.2
1.2.0
...
„Major.Minor“-Versionsverwaltung mit Alpha-, Beta- und Candidate-Vorabversionen
0.9
1.0a1
1.0a2
1.0b1
1.0rc1
1.0
1.1a1
...
„Major.Minor“-Versionsverwaltung mit Entwicklungsversionen, Release-Kandidaten und Post-Releases für kleinere Korrekturen
0.9
1.0.dev1
1.0.dev2
1.0.dev3
1.0.dev4
1.0c1
1.0c2
1.0
1.0.post1
1.1.dev1
...
Datumsbasierte Releases mit fortlaufender Seriennummer pro Jahr, wobei Null übersprungen wird
2012.1
2012.2
2012.3
...
2012.15
2013.1
2013.2
...
Zusammenfassung der zulässigen Suffixe und relative Reihenfolge
Hinweis
Dieser Abschnitt richtet sich in erster Linie an Autoren von Werkzeugen, die Distributionsmetadaten automatisch verarbeiten, und nicht an Entwickler von Python-Distributionen, die sich für ein Versionsverwaltungsschema entscheiden.
Das Epoch-Segment von Versionsbezeichnern MUSS entsprechend dem numerischen Wert des gegebenen Epoch sortiert werden. Wenn kein Epoch-Segment vorhanden ist, ist der implizite numerische Wert 0.
Das Release-Segment von Versionsbezeichnern MUSS in derselben Reihenfolge sortiert werden wie die Tupelsortierung von Python, wenn das normalisierte Release-Segment wie folgt geparst wird
tuple(map(int, release_segment.split(".")))
Alle beteiligten Release-Segmente MÜSSEN durch Auffüllen kürzerer Segmente mit Nullen auf eine konsistente Länge umgewandelt werden.
Innerhalb eines numerischen Releases (1.0, 2.7.3) sind die folgenden Suffixe zulässig und MÜSSEN wie gezeigt geordnet werden
.devN, aN, bN, rcN, <no suffix>, .postN
Beachten Sie, dass c semantisch äquivalent zu rc ist und so sortiert werden muss, als wäre es rc. Werkzeuge DÜRFEN den Fall, dass derselbe N sowohl für ein c als auch für ein rc im selben Release-Segment vorkommt, als missverständlich ablehnen und weiterhin mit der PEP konform bleiben.
Innerhalb eines Alpha (1.0a1), Beta (1.0b1) oder Release Candidate (1.0rc1, 1.0c1) sind die folgenden Suffixe zulässig und MÜSSEN wie gezeigt geordnet werden
.devN, <no suffix>, .postN
Innerhalb eines Post-Releases (1.0.post1) sind die folgenden Suffixe zulässig und MÜSSEN wie gezeigt geordnet werden
.devN, <no suffix>
Beachten Sie, dass devN und postN IMMER einem Punkt vorangestellt sein MÜSSEN, auch wenn sie unmittelbar nach einer numerischen Version verwendet werden (z. B. 1.0.dev456, 1.0.post1).
Innerhalb eines Vorab-, Post- oder Entwicklungsrelease-Segments mit einem gemeinsamen Präfix muss die Sortierung nach dem Wert der numerischen Komponente erfolgen.
Das folgende Beispiel deckt viele der möglichen Kombinationen ab
1.dev0
1.0.dev456
1.0a1
1.0a2.dev456
1.0a12.dev456
1.0a12
1.0b1.dev456
1.0b2
1.0b2.post345.dev456
1.0b2.post345
1.0rc1.dev456
1.0rc1
1.0
1.0+abc.5
1.0+abc.7
1.0+5
1.0.post456.dev34
1.0.post456
1.0.15
1.1.dev1
Versionsreihenfolge über verschiedene Metadatenversionen hinweg
Metadaten v1.0 (PEP 241) und Metadaten v1.1 (PEP 314) definieren kein standardisiertes Versionsidentifikations- oder Sortierungsschema. Metadaten v1.2 (PEP 345) definieren jedoch ein Schema, das in PEP 386 festgelegt ist.
Aufgrund der Natur der einfachen Installer-API ist es einem Installer nicht möglich, zu wissen, welche Metadatenversion eine bestimmte Distribution verwendet hat. Zusätzlich benötigten Installer die Möglichkeit, eine vernünftig priorisierte Liste zu erstellen, die alle, oder so viele wie möglich, Versionen eines Projekts enthält, um festzustellen, welche Versionen installiert werden sollten. Diese Anforderungen machen eine Standardisierung eines einzigen Parsing-Mechanismus für alle Versionen eines Projekts notwendig.
Aus den oben genannten Gründen MUSS diese PEP für alle Metadatenversionen verwendet werden und ersetzt PEP 386, auch für Metadaten v1.2. Werkzeuge SOLLTEN alle Versionen ignorieren, die nicht nach den Regeln dieser PEP geparst werden können, DÜRFEN aber auf implementierungsdefinierte Version-Parsing- und Sortierungsschemata zurückgreifen, wenn keine Versionen verfügbar sind, die mit dieser PEP konform sind.
Distributionsbenutzer möchten möglicherweise nicht konforme Versionen aus privaten Paketindizes, die sie kontrollieren, explizit entfernen.
Kompatibilität mit anderen Versionsschemata
Einige Projekte entscheiden sich möglicherweise für ein Versionsschema, das eine Übersetzung erfordert, um dem öffentlichen Versionsschema, das in dieser PEP definiert ist, zu entsprechen. In solchen Fällen können die projektspezifische Version in den Metadaten gespeichert und die übersetzte öffentliche Version im Versionsfeld veröffentlicht werden.
Dies ermöglicht es automatisierten Distributionswerkzeugen, eine konsistent korrekte Sortierung veröffentlichter Releases bereitzustellen, während Entwickler weiterhin das interne Versionsschema verwenden können, das sie für ihre Projekte bevorzugen.
Semantische Versionierung
Semantische Versionierung ist ein beliebtes Versionsidentifikationsschema, das präskriptiver ist als diese PEP hinsichtlich der Bedeutung verschiedener Elemente einer Release-Nummer. Selbst wenn ein Projekt beschließt, sich nicht an die Details der semantischen Versionierung zu halten, ist das Schema lohnenswert zu verstehen, da es viele Probleme abdeckt, die auftreten können, wenn man von anderen Distributionen abhängt und eine Distribution veröffentlicht, auf die sich andere verlassen.
Die Aspekte „Major.Minor.Patch“ (in dieser PEP als „major.minor.micro“ beschrieben) der semantischen Versionierung (Abschnitte 1-8 der Spezifikation 2.0.0) sind vollständig mit dem in dieser PEP definierten Versionsschema kompatibel, und die Einhaltung dieser Aspekte wird gefördert.
Semantische Versionen, die einen Bindestrich (Vorabversionen – Abschnitt 10) oder ein Pluszeichen (Builds – Abschnitt 11) enthalten, sind nicht mit dieser PEP kompatibel und sind im öffentlichen Versionsfeld nicht zulässig.
Ein möglicher Mechanismus zur Übersetzung solcher semantischen Versionierungs-basierter Quell-Labels in kompatible öffentliche Versionen ist die Verwendung des Suffixes .devN, um die entsprechende Versionenreihenfolge anzugeben.
Spezifische Build-Informationen können auch in lokalen Versions-Labels enthalten sein.
DVCS-basierte Versionskennzeichnungen
Viele Build-Werkzeuge integrieren sich mit verteilten Versionskontrollsystemen wie Git und Mercurial, um eine identifizierende Hash-Summe zum Versionsbezeichner hinzuzufügen. Da Hash-Summen nicht zuverlässig geordnet werden können, sind solche Versionen im öffentlichen Versionsfeld nicht zulässig.
Wie bei der semantischen Versionierung kann das öffentliche Suffix .devN verwendet werden, um solche Releases für die Veröffentlichung eindeutig zu identifizieren, während das ursprüngliche DVCS-basierte Label in den Projektmetadaten gespeichert werden kann.
Identifizierende Hash-Informationen können auch in lokalen Versions-Labels enthalten sein.
Olson-Datenbank-Versionierung
Das Projekt pytz erbt sein Versionsverwaltungsschema vom entsprechenden Olson-Zeitzonendatenbank-Versionsverwaltungsschema: das Jahr gefolgt von einem Kleinbuchstaben, der die Version der Datenbank innerhalb dieses Jahres angibt.
Dies kann in einen konformen öffentlichen Versionsbezeichner als <Jahr>.<Serie> übersetzt werden, wobei die Serie bei null oder eins beginnt (für das Release „<Jahr>a“) und bei jeder nachfolgenden Datenbankaktualisierung innerhalb des Jahres inkrementiert wird.
Wie bei anderen übersetzten Versionsbezeichnern könnte die entsprechende Olson-Datenbankversion in den Projektmetadaten aufgezeichnet werden.
Versionsspezifikatoren
Ein Versionsspezifikator besteht aus einer Reihe von Versionsklauseln, die durch Kommas getrennt sind. Zum Beispiel
~= 0.9, >= 1.0, != 1.3.4.*, < 2.0
Der Vergleichsoperator bestimmt die Art der Versionsklausel
~=: Kompatible Release-Klausel==: Versionsabgleich-Klausel!=: Versionsausschluss-Klausel<=,>=: Inklusive geordnete Vergleichsklausel<,>: Exklusive geordnete Vergleichsklausel===: Beliebige Gleichheitsklausel.
Das Komma („,“) ist äquivalent zu einem logischen und-Operator: Eine Kandidatenversion muss allen gegebenen Versionsklauseln entsprechen, um den Spezifikator als Ganzes zu erfüllen.
Leerzeichen zwischen einem Bedingungsoperator und dem folgenden Versionsbezeichner sind optional, ebenso wie Leerzeichen um die Kommas.
Wenn mehrere Kandidatenversionen einen Versionsspezifikator erfüllen, SOLLTE die bevorzugte Version die neueste Version sein, wie sie durch die konsistente Sortierung gemäß dem Standard-Versionsschema bestimmt wird. Ob Vorabversionen als Kandidatenversionen betrachtet werden oder nicht, SOLLTE wie in Umgang mit Vorabversionen beschrieben gehandhabt werden.
Sofern nicht ausdrücklich unten angegeben, dürfen lokale Versionsbezeichner in Versionsspezifikatoren NICHT zulässig sein, und lokale Versions-Labels MÜSSEN bei der Überprüfung, ob Kandidatenversionen einen gegebenen Versionsspezifikator erfüllen, vollständig ignoriert werden.
Kompatible Veröffentlichung
Eine kompatible Release-Klausel besteht aus dem Operator für kompatible Releases ~= und einem Versionsbezeichner. Sie entspricht jeder Kandidatenversion, die als kompatibel mit der angegebenen Version angesehen wird.
Der angegebene Versionsbezeichner muss im Standardformat gemäß Versionsschema vorliegen. Lokale Versionsbezeichner sind in diesem Versionsspezifikator NICHT zulässig.
Für einen gegebenen Release-Bezeichner V.N ist die kompatible Release-Klausel annähernd äquivalent zum Paar von Vergleichsklauseln
>= V.N, == V.*
Dieser Operator darf NICHT mit einer Versionsnummer mit nur einem Segment verwendet werden, wie z. B. ~=1.
Zum Beispiel sind die folgenden Gruppen von Versionsklauseln äquivalent
~= 2.2
>= 2.2, == 2.*
~= 1.4.5
>= 1.4.5, == 1.4.*
Wenn ein Vorab-, Post- oder Entwicklungsrelease in einer kompatiblen Release-Klausel als V.N.suffix benannt wird, wird das Suffix bei der Bestimmung des erforderlichen Präfix-Abgleichs ignoriert.
~= 2.2.post3
>= 2.2.post3, == 2.*
~= 1.4.5a4
>= 1.4.5a4, == 1.4.*
Die Auffüllregeln für Vergleiche von Release-Segmenten bedeuten, dass der angenommene Grad der Vorwärtskompatibilität in einer kompatiblen Release-Klausel durch Anhängen zusätzlicher Nullen an den Versionsspezifikator gesteuert werden kann.
~= 2.2.0
>= 2.2.0, == 2.2.*
~= 1.4.5.0
>= 1.4.5.0, == 1.4.5.*
Versionsabgleich
Eine Versionsabgleich-Klausel enthält den Versionsabgleich-Operator == und einen Versionsbezeichner.
Der angegebene Versionsbezeichner muss im Standardformat gemäß Versionsschema vorliegen, aber ein nachgestelltes .* ist bei öffentlichen Versionsbezeichnern zulässig, wie unten beschrieben.
Standardmäßig basiert der Versionsabgleich-Operator auf einem strikten Gleichheitsvergleich: Der angegebene Versionsbezeichner muss exakt mit der angeforderten Version übereinstimmen. Die *einzige* durchgeführte Ersetzung ist die Nullauffüllung des Release-Segments, um sicherzustellen, dass die Release-Segmente mit der gleichen Länge verglichen werden.
Ob ein strikter Versionsabgleich angemessen ist, hängt vom spezifischen Anwendungsfall des Versionsspezifikators ab. Automatisierte Werkzeuge SOLLTEN mindestens Warnungen ausgeben und DÜRFEN sie vollständig ablehnen, wenn strikte Versionsabgleiche unangemessen verwendet werden.
Anstelle eines strikten Vergleichs kann ein Präfix-Abgleich angefordert werden, indem ein nachgestelltes .* an den Versionsbezeichner in der Versionsabgleich-Klausel angehängt wird. Das bedeutet, dass zusätzliche nachgestellte Segmente ignoriert werden, wenn bestimmt wird, ob ein Versionsbezeichner die Klausel erfüllt. Wenn die angegebene Version nur ein Release-Segment enthält, werden nachgestellte Komponenten (oder deren Fehlen) im Release-Segment ebenfalls ignoriert.
Zum Beispiel würden bei der Version 1.1.post1 die folgenden Klauseln wie gezeigt übereinstimmen oder nicht
== 1.1 # Not equal, so 1.1.post1 does not match clause
== 1.1.post1 # Equal, so 1.1.post1 matches clause
== 1.1.* # Same prefix, so 1.1.post1 matches clause
Für den Präfix-Abgleich wird das Vorabversions-Segment als mit einem impliziten vorangestellten Punkt betrachtet. Bei der Version 1.1a1 würden die folgenden Klauseln wie gezeigt übereinstimmen oder nicht
== 1.1 # Not equal, so 1.1a1 does not match clause
== 1.1a1 # Equal, so 1.1a1 matches clause
== 1.1.* # Same prefix, so 1.1a1 matches clause if pre-releases are requested
Eine exakte Übereinstimmung gilt auch als Präfix-Übereinstimmung (diese Interpretation ist durch die üblichen Nullauffüllregeln für das Release-Segment von Versionsbezeichnern impliziert). Bei der Version 1.1 würden die folgenden Klauseln wie gezeigt übereinstimmen oder nicht
== 1.1 # Equal, so 1.1 matches clause
== 1.1.0 # Zero padding expands 1.1 to 1.1.0, so it matches clause
== 1.1.dev1 # Not equal (dev-release), so 1.1 does not match clause
== 1.1a1 # Not equal (pre-release), so 1.1 does not match clause
== 1.1.post1 # Not equal (post-release), so 1.1 does not match clause
== 1.1.* # Same prefix, so 1.1 matches clause
Es ist ungültig, einen Präfix-Abgleich mit einer Entwicklungs- oder lokalen Version zu haben, wie z. B. 1.0.dev1.* oder 1.0+foo1.*. Falls vorhanden, ist das Entwicklungsrelease-Segment immer das letzte Segment in der öffentlichen Version, und die lokale Version wird für Vergleichszwecke ignoriert, sodass die Verwendung in einem Präfix-Abgleich keinen Sinn ergeben würde.
Die Verwendung von == (ohne mindestens das Wildcard-Suffix) bei der Definition von Abhängigkeiten für veröffentlichte Distributionen wird dringend abgeraten, da sie die Bereitstellung von Sicherheitsupdates erheblich erschwert. Der strikte Versionsvergleichsoperator ist hauptsächlich für die Definition von Abhängigkeiten für wiederholbare *Anwendungsdeployments* bei Verwendung eines gemeinsamen Distributionsindexes vorgesehen.
Wenn der angegebene Versionsbezeichner ein öffentlicher Versionsbezeichner ist (kein lokales Versions-Label), dann MUSS das lokale Versions-Label aller Kandidatenversionen beim Abgleich von Versionen ignoriert werden.
Wenn der angegebene Versionsbezeichner ein lokaler Versionsbezeichner ist, dann MÜSSEN die lokalen Versions-Labels von Kandidatenversionen beim Abgleich von Versionen berücksichtigt werden, wobei der öffentliche Versionsbezeichner wie oben beschrieben abgeglichen wird und das lokale Versions-Label auf Gleichheit mittels strikten Zeichenketten-Gleichheitsvergleichs geprüft wird.
Versionen ausschließen
Eine Versionsausschluss-Klausel enthält den Versionsausschluss-Operator != und einen Versionsbezeichner.
Die zulässigen Versionsbezeichner und Vergleichssemantiken sind dieselben wie die des Versionsabgleichs-Operators, außer dass die Bedeutung jedes Abgleichs invertiert ist.
Zum Beispiel würden bei der Version 1.1.post1 die folgenden Klauseln wie gezeigt übereinstimmen oder nicht
!= 1.1 # Not equal, so 1.1.post1 matches clause
!= 1.1.post1 # Equal, so 1.1.post1 does not match clause
!= 1.1.* # Same prefix, so 1.1.post1 does not match clause
Inklusive geordneter Vergleich
Eine inklusive geordnete Vergleichsklausel enthält einen Vergleichsoperator und einen Versionsbezeichner und entspricht jeder Version, bei der der Vergleich korrekt ist, basierend auf der relativen Position der Kandidatenversion und der angegebenen Version gemäß der konsistenten Sortierung, die durch das Standard-Versionsschema definiert ist.
Die inklusiven geordneten Vergleichsoperatoren sind <= und >=.
Wie beim Versionsabgleich wird das Release-Segment nach Bedarf mit Nullen aufgefüllt, um sicherzustellen, dass die Release-Segmente mit der gleichen Länge verglichen werden.
Lokale Versionsbezeichner sind in diesem Versionsspezifikator NICHT zulässig.
Exklusive geordneter Vergleich
Die exklusiven geordneten Vergleiche > und < ähneln den inklusiven geordneten Vergleichen, da sie auf der relativen Position der Kandidatenversion und der angegebenen Version basieren, gemäß der konsistenten Sortierung, die durch das Standard-Versionsschema definiert ist. Sie schließen jedoch ausdrücklich Vorabversionen, Post-Releases und lokale Versionen der angegebenen Version aus.
Der exklusive geordnete Vergleich >V darf KEINE Post-Releases der gegebenen Version zulassen, es sei denn, V ist selbst ein Post-Release. Sie können erzwingen, dass Releases später als ein bestimmtes Post-Release sind, einschließlich zusätzlicher Post-Releases, indem Sie >V.postN verwenden. Zum Beispiel erlaubt >1.7 1.7.1, aber nicht 1.7.0.post1 und >1.7.post2 erlaubt 1.7.1 und 1.7.0.post3, aber nicht 1.7.0.
Der exklusive geordnete Vergleich >V darf KEINE lokale Version der angegebenen Version entsprechen.
Der exklusive geordnete Vergleich <V darf KEINE Vorabversion der angegebenen Version zulassen, es sei denn, die angegebene Version ist selbst eine Vorabversion. Das Zulassen von Vorabversionen, die früher als eine bestimmte Vorabversion sind, aber nicht gleich, kann durch die Verwendung von <V.rc1 oder ähnlichem erreicht werden.
Wie beim Versionsabgleich wird das Release-Segment nach Bedarf mit Nullen aufgefüllt, um sicherzustellen, dass die Release-Segmente mit der gleichen Länge verglichen werden.
Lokale Versionsbezeichner sind in diesem Versionsspezifikator NICHT zulässig.
Beliebige Gleichheit
Beliebige Gleichheitsvergleiche sind einfache Zeichenketten-Gleichheitsoperationen, die keine semantischen Informationen wie Nullauffüllung oder lokale Versionen berücksichtigen. Dieser Operator unterstützt auch keinen Präfix-Abgleich, wie es der Operator == tut.
Der Hauptanwendungsfall für beliebige Gleichheit ist die Ermöglichung der Spezifikation einer Version, die auf andere Weise nicht durch diese PEP dargestellt werden kann. Dieser Operator ist besonders und fungiert als Fluchtweg, um jemandem, der ein Werkzeug verwendet, das diese PEP implementiert, die Installation einer Legacy-Version zu ermöglichen, die ansonsten inkompatibel mit dieser PEP ist.
Ein Beispiel wäre ===foobar, das einer Version von foobar entsprechen würde.
Dieser Operator kann auch verwendet werden, um explizit eine ungepatchte Version eines Projekts zu fordern, wie z. B. ===1.0, was für eine Version 1.0+downstream1 nicht zutreffen würde.
Die Verwendung dieses Operators wird dringend abgeraten und Werkzeuge KÖNNEN eine Warnung anzeigen, wenn er verwendet wird.
Umgang mit Vorab-Veröffentlichungen
Vorabversionen jeglicher Art, einschließlich Entwicklungsversionen, sind von allen Versionsspezifikatoren implizit ausgeschlossen, *es sei denn*, sie sind bereits auf dem System vorhanden, werden vom Benutzer explizit angefordert oder wenn die einzige verfügbare Version, die den Versionsspezifikator erfüllt, eine Vorabversion ist.
Standardmäßig SOLLTEN Abhängigkeitsauflösungswerkzeuge
- bereits installierte Vorabversionen für alle Versionsspezifikatoren akzeptieren
- entfernt verfügbare Vorabversionen für Versionsspezifikatoren akzeptieren, für die keine finale oder Post-Version den Versionsspezifikator erfüllt
- alle anderen Vorabversionen von der Betrachtung ausschließen
Abhängigkeitsauflösungswerkzeuge KÖNNEN eine Warnung ausgeben, wenn eine Vorabversion zur Erfüllung eines Versionsspezifikators benötigt wird.
Abhängigkeitsauflösungswerkzeuge SOLLTEN den Benutzern auch erlauben, die folgenden alternativen Verhaltensweisen anzufordern
- Akzeptieren von Vorabversionen für alle Versionsspezifikatoren
- Ausschließen von Vorabversionen für alle Versionsspezifikatoren (Fehler- oder Warnmeldung, wenn eine Vorabversion lokal bereits installiert ist oder wenn eine Vorabversion die einzige Möglichkeit ist, einen bestimmten Spezifikator zu erfüllen)
Abhängigkeitsauflösungswerkzeuge KÖNNEN auch erlauben, dass das oben genannte Verhalten pro Distribution gesteuert wird.
Post-Releases und finale Releases erhalten keine besondere Behandlung in Versionsspezifikatoren – sie werden immer eingeschlossen, es sei denn, sie werden explizit ausgeschlossen.
Beispiele
~=3.1: Version 3.1 oder neuer, aber nicht Version 4.0 oder neuer.~=3.1.2: Version 3.1.2 oder neuer, aber nicht Version 3.2.0 oder neuer.~=3.1a1: Version 3.1a1 oder neuer, aber nicht Version 4.0 oder neuer.== 3.1: speziell Version 3.1 (oder 3.1.0), schließt alle Vorabversionen, Post-Releases, Entwicklungsversionen und alle 3.1.x Wartungsreleases aus.== 3.1.*: jede Version, die mit 3.1 beginnt. Äquivalent zur kompatiblen Release-Klausel~=3.1.0.~=3.1.0, != 3.1.3: Version 3.1.0 oder neuer, aber nicht Version 3.1.3 und nicht Version 3.2.0 oder neuer.
Direkte Referenzen
Einige automatisierte Werkzeuge erlauben möglicherweise die Verwendung einer direkten Referenz als Alternative zu einem normalen Versionsspezifikator. Eine direkte Referenz besteht aus dem Spezifikator @ und einer expliziten URL.
Ob direkte Referenzen angemessen sind, hängt vom spezifischen Anwendungsfall des Versionsspezifikators ab. Automatisierte Werkzeuge SOLLTEN mindestens Warnungen ausgeben und DÜRFEN sie vollständig ablehnen, wenn direkte Referenzen unangemessen verwendet werden.
Öffentliche Indexserver SOLLTEN die Verwendung von direkten Referenzen in hochgeladenen Distributionen NICHT zulassen. Direkte Referenzen sind als Werkzeug für Softwareintegratoren und nicht für Publisher gedacht.
Abhängig vom Anwendungsfall können einige geeignete Ziele für eine direkte URL-Referenz ein sdist- oder ein Wheel-Binärarchiv sein. Die genauen unterstützten URLs und Ziele sind werkzeugabhängig.
Zum Beispiel kann ein lokales Quellarchiv direkt referenziert werden
pip @ file:///localbuilds/pip-1.3.1.zip
Alternativ kann auch ein vortrainiertes Archiv referenziert werden
pip @ file:///localbuilds/pip-1.3.1-py33-none-any.whl
Alle direkten Referenzen, die sich nicht auf eine lokale Datei-URL beziehen, SOLLTEN einen sicheren Transportmechanismus (wie z. B. https) angeben UND einen erwarteten Hash-Wert in der URL zur Verifizierung enthalten. Wenn eine direkte Referenz ohne Hash-Informationen, mit Hash-Informationen, die das Werkzeug nicht versteht, oder mit einem ausgewählten Hash-Algorithmus, den das Werkzeug als zu schwach zum Vertrauen erachtet, angegeben wird, SOLLTEN automatisierte Werkzeuge mindestens eine Warnung ausgeben und DÜRFEN sich nicht auf die URL verlassen. Wenn eine solche direkte Referenz auch einen unsicheren Transport verwendet, SOLLTEN automatisierte Werkzeuge die URL NICHT verwenden.
Es wird EMPOHLEN, nur Hashes zu verwenden, die bedingungslos von der neuesten Version des Standardbibliotheksmoduls hashlib bereitgestellt werden. Zum Zeitpunkt der Erstellung besteht diese Liste aus 'md5', 'sha1', 'sha224', 'sha256', 'sha384' und 'sha512'.
Für Quellarchiv- und Wheel-Referenzen kann ein erwarteter Hash-Wert angegeben werden, indem ein Eintrag <hash-algorithm>=<expected-hash> als Teil des URL-Fragments enthalten ist.
Für Versionskontrollreferenzen SOLLTE das Schema VCS+protocol verwendet werden, um sowohl das Versionskontrollsystem als auch den sicheren Transport zu identifizieren, und ein Versionskontrollsystem mit hashbasierten Commit-Identifikatoren SOLLTE verwendet werden. Automatisierte Werkzeuge DÜRFEN Warnungen über fehlende Hashes für Versionskontrollsysteme weglassen, die keine hashbasierten Commit-Identifikatoren bereitstellen.
Um Versionskontrollsysteme zu handhaben, die keine Commit- oder Tag-Referenzen direkt in der URL unterstützen, können diese Informationen am Ende der URL mit der Notation @<commit-hash> oder @<tag>#<commit-hash> angehängt werden.
Hinweis
Dies ist *nicht ganz* dasselbe wie die bestehende VCS-Referenznotation, die von pip unterstützt wird. Erstens wird der Distributionsname vorne platziert, anstatt als Teil der URL eingebettet zu werden. Zweitens ist der Commit-Hash auch dann enthalten, wenn basierend auf einem Tag abgerufen wird, um die Anforderung zu erfüllen, dass *jeder* Link einen Hash enthalten soll, um das Fälschen zu erschweren (ein bösartiges Repository mit einem bestimmten Tag zu erstellen ist einfach, mit einem bestimmten *Hash*, weniger so).
Beispiele für Remote-URLs
pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686
pip @ git+https://github.com/pypa/pip.git@7921be1537eac1e97bc40179a57f0349c2aee67d
pip @ git+https://github.com/pypa/pip.git@1.3.1#7921be1537eac1e97bc40179a57f0349c2aee67d
Datei-URLs
Datei-URLs haben das Format file://<host>/<pfad>. Wenn der <host> weggelassen wird, wird angenommen, dass es sich um localhost handelt, und selbst wenn der <host> weggelassen wird, MUSS der dritte Schrägstrich immer noch vorhanden sein. Der <pfad> definiert den Dateipfad im Dateisystem, auf den zugegriffen werden soll.
Auf den verschiedenen *nix-Betriebssystemen sind die einzigen zulässigen Werte für <host>, dass er weggelassen wird, localhost oder ein anderer FQDN, den die aktuelle Maschine als ihren eigenen Host betrachtet. Mit anderen Worten, unter *nix kann das file://-Schema nur verwendet werden, um auf Pfade auf dem lokalen Rechner zuzugreifen.
Unter Windows sollte das Dateiformat den Laufwerksbuchstaben, falls zutreffend, als Teil des <pfad> enthalten (z. B. file:///c:/path/to/a/file). Im Gegensatz zu *nix kann unter Windows der <host>-Parameter verwendet werden, um eine Datei auf einem Netzwerkshare anzugeben. Mit anderen Worten, um \\machine\volume\file in eine file://-URL zu übersetzen, würde dies zu file://machine/volume/file führen. Weitere Informationen zu file://-URLs unter Windows finden Sie in MSDN [4].
Aktualisierung der Versionsspezifikation
Die Versionsspezifikation kann mit Klarstellungen aktualisiert werden, ohne dass eine neue PEP oder eine Änderung der Metadatenversion erforderlich ist.
Jegliche technischen Änderungen, die sich auf die Syntax und Semantik der Versionsidentifikation und des Vergleichs auswirken, würden eine aktualisierte Versionsspezifikation erfordern, die in einer neuen PEP definiert wird.
Zusammenfassung der Unterschiede zu pkg_resources.parse_version
- Hinweis: Dieser Vergleich bezieht sich auf
pkg_resourses.parse_version, wie sie zum Zeitpunkt der Erstellung der PEP existierte. Nach Annahme der PEP haben setuptools 6.0 und spätere Versionen das in dieser PEP beschriebene Verhalten übernommen. - Lokale Versionen werden anders sortiert; diese PEP verlangt, dass sie als größer als die gleiche Version ohne lokale Version sortiert werden, während
pkg_resources.parse_versionsie als Vorabversionsmarker betrachtet. - Diese PEP beschränkt bewusst die Syntax, die eine gültige Version darstellt, während
pkg_resources.parse_versionversucht, eine Bedeutung aus *beliebigen* Zeichenketten zu gewinnen. pkg_resources.parse_versionerlaubt beliebig tief verschachtelte Versionsbezeichner wie1.0.dev1.post1.dev5. Diese PEP erlaubt jedoch nur eine einzige Verwendung jedes Typs, und sie müssen in einer bestimmten Reihenfolge vorkommen.
Zusammenfassung der Unterschiede zu PEP 386
- Beschreibung der Versionsspezifikatoren in die Versions-PEP verschoben
- Das Konzept der „direkten Referenz“ als Standardnotation für direkte Referenzen zu Ressourcen hinzugefügt (anstatt dass jedes Werkzeug sein eigenes erfinden muss)
- Die Konzepte „lokaler Versionsbezeichner“ und „lokales Versions-Label“ hinzugefügt, damit Systemintegratoren gepatchte Builds auf eine Weise kennzeichnen können, die von den Upstream-Werkzeugen unterstützt wird, sowie um die Einbeziehung von Build-Tags in die Versionierung von Binärdistributionen zu ermöglichen.
- Die Klausel „kompatibles Release“ hinzugefügt
- Fügte die Syntax für nachgestellte Wildcards für die Versionsabgleichung und den Ausschluss basierend auf Präfixen hinzu
- Änderte die Sortierposition auf oberster Ebene des Suffixes
.devN - Erlaubte Versionsnummern mit einem einzigen Wert
- Expliziter Ausschluss von führenden oder nachgestellten Leerzeichen
- Explizite Unterstützung für datumsbasierte Versionen
- Explizite Normalisierungsregeln zur Verbesserung der Kompatibilität mit vorhandenen Versionsmetadaten auf PyPI, wo dies keine Mehrdeutigkeit einführt
- Schließt Prä-Releases implizit aus, es sei denn, sie sind bereits vorhanden oder werden benötigt, um eine Abhängigkeit zu erfüllen
- Behandelt Post-Releases genauso wie nicht qualifizierte Releases
- Diskutiert die Reihenfolge und Abhängigkeiten über Metadatenversionen hinweg
- Umstellung von der Bevorzugung von
czurc.
Die Begründung für wesentliche Änderungen wird in den folgenden Abschnitten gegeben.
Änderung des Versionsschemas
Eine wesentliche Änderung am Versionsschema in diesem PEP im Vergleich zu PEP 386 besteht darin, entwicklungsrelevante Releases auf oberster Ebene wie X.Y.devN vor Alpha-Releases wie X.Ya1 zu sortieren. Dies ist eine weitaus logischere Sortierreihenfolge, da Projekte, die sowohl Entwicklungsreleases als auch Alphas/Betas/Release Candidates verwenden, nicht möchten, dass ihre Entwicklungsreleases zwischen ihren Release Candidates und ihren endgültigen Releases sortiert werden. Es gibt keine Begründung dafür, dev-Releases an dieser Stelle zu verwenden, anstatt lediglich zusätzliche Release Candidates zu erstellen.
Die aktualisierte Sortierreihenfolge bedeutet auch, dass die Sortierung von dev-Versionen nun konsistent zwischen dem Metadatenstandard und dem vorbestehenden Verhalten von pkg_resources (und damit dem Verhalten aktueller Installationstools) ist.
Diese Änderung sollte es für betroffene bestehende Projekte einfacher machen, auf die neueste Version des Metadatenstandards zu migrieren.
Eine weitere Änderung am Versionsschema ist die Zulassung von Einzelnummer-Versionen, ähnlich denen, die von Nicht-Python-Projekten wie Mozilla Firefox, Google Chrome und der Fedora Linux-Distribution verwendet werden. Dies wird tatsächlich voraussichtlich nützlicher für Versionsspezifizierer sein, aber es ist einfacher, es sowohl für Versionsspezifizierer als auch für Release-Nummern zuzulassen, anstatt die beiden Definitionen zu trennen.
Der Ausschluss von führenden und nachgestellten Leerzeichen wurde explizit gemacht, nachdem ein paar Projekte mit Versionsbezeichnern gefunden wurden, die sich nur durch ein nachgestelltes \n-Zeichen unterschieden und auf PyPI vorhanden waren.
Verschiedene andere Normalisierungsregeln wurden ebenfalls hinzugefügt, wie im separaten Abschnitt zur Versionsnormalisierung unten beschrieben.
Anhang A zeigt detaillierte Ergebnisse einer Analyse von PyPI-Distributionsversionsinformationen, wie sie am 8. August 2014 gesammelt wurden. Diese Analyse vergleicht das Verhalten des explizit geordneten Versionsschemas, das in diesem PEP definiert ist, mit dem De-facto-Standard, der durch das Verhalten von setuptools definiert ist. Diese Metriken sind nützlich, da die Absicht dieses PEP darin besteht, dem bestehenden Verhalten von setuptools so genau wie möglich zu folgen, während gleichzeitig Ausnahmen für nicht sortierbare Versionen gemacht werden (anstatt zu versuchen, eine geeignete Reihenfolge zu erraten, wie es setuptools tut).
Eine meinungsfreundlichere Beschreibung des Versionsschemas
Wie in PEP 386 liegt der Schwerpunkt darauf, bestehende Praktiken zu kodifizieren, um sie besser für die Automatisierung geeignet zu machen, anstatt von bestehenden Projekten zu verlangen, dass sie nicht-triviale Änderungen an ihrem Workflow vornehmen. Das Standardschema erlaubt jedoch erheblich mehr Flexibilität, als für die überwiegende Mehrheit einfacher Python-Pakete erforderlich ist (die oft nicht einmal Wartungsreleases benötigen – viele Benutzer sind zufrieden damit, auf ein neues Feature-Release aktualisieren zu müssen, um Fehlerbehebungen zu erhalten).
Zum Nutzen von unerfahrenen Entwicklern und von erfahrenen Entwicklern, die die verschiedenen Anwendungsfälle besser verstehen möchten, geht die Spezifikation nun viel detaillierter auf die Komponenten des definierten Versionsschemas ein, einschließlich Beispielen, wie jede Komponente in der Praxis verwendet werden kann.
Das PEP weist die Entwickler auch explizit in Richtung semantischer Versionierung (ohne diese zu verlangen) und rät von der Verwendung mehrerer Aspekte des vollständigen Versionierungsschemas ab, die weitgehend aufgenommen wurden, um esoterische Eckfälle in den Praktiken bestehender Projekte und bei der Neuverpackung von Software für Linux-Distributionen abzudecken.
Beschreibung von Versionsspezifikatoren neben dem Versionsschema
Der Hauptgrund für die überhaupt vorhandene standardisierte Versionsschema besteht darin, zuverlässige automatisierte Abhängigkeitsanalysen zu erleichtern. Es ist sinnvoller, den primären Anwendungsfall für Versionsbezeichner neben ihrer Definition zu beschreiben.
Änderung der Interpretation von Versionsspezifikatoren
Die frühere Interpretation von Versionsspezifizierern machte es sehr einfach, versehentlich eine Prä-Release-Version einer Abhängigkeit herunterzuladen. Dies erschwerte es wiederum den Entwicklern, Prä-Release-Versionen von Software im Python Package Index zu veröffentlichen, da selbst die Kennzeichnung des Pakets als "versteckt" nicht ausreichte, um automatisierte Tools vom Herunterladen abzuhalten, und es den Benutzern auch erschwerte, die Testversion manuell über die Haupt-PyPI-Weboberfläche zu erhalten.
Die frühere Interpretation schloss auch Post-Releases aus einigen Versionsspezifizierern ohne ausreichend begründeten Grund aus.
Die aktualisierte Interpretation soll es schwierig machen, versehentlich eine Prä-Release-Version als erfüllende Abhängigkeit zu akzeptieren, während Prä-Release-Versionen weiterhin automatisch abgerufen werden können, wenn dies die einzige Möglichkeit ist, eine Abhängigkeit zu erfüllen.
Die Versionsbeschränkung "einige Vorwärtskompatibilität angenommen" leitet sich vom Operator für "pessimistische Versionsbeschränkung" der Ruby-Community [2] ab, um Projekten zu ermöglichen, einen vorsichtigen Ansatz für Vorwärtskompatibilitätsversprechen zu verfolgen und gleichzeitig eine Mindestanforderung für ihre Abhängigkeiten einfach festzulegen. Die Schreibweise der Klausel für kompatible Releases (~=) ist von den Ruby- (~>) und PHP- (~) Äquivalenten inspiriert.
Weitere Verbesserungen sind für die Handhabung der parallelen Installation mehrerer Versionen derselben Bibliothek geplant, diese werden jedoch von Aktualisierungen der Installationsdatenbankdefinition sowie von verbesserten Tools für die dynamische Pfadmanipulation abhängen.
Die Syntax für nachgestellte Wildcards zur Anforderung von präfixbasierter Versionsabgleichung wurde hinzugefügt, um die sinnvolle Definition von Klauseln für kompatible Releases zu ermöglichen.
Unterstützung für datumsbasierte Versionskennungen
Der Ausschluss datumsbasierter Versionen verursachte erhebliche Probleme bei der Migration von pytz zu den neuen Metadatenstandards. Er löste auch Bedenken bei den OpenStack-Entwicklern aus, da diese ein datumsbasiertes Versionierungsschema verwenden und zu den neuen Metadatenstandards migrieren möchten, ohne es zu ändern.
Hinzufügen von Versionsepochen
Versions-Epochen werden aus demselben Grund hinzugefügt, aus dem sie Teil anderer Versionierungsschemata sind, wie z. B. die der Fedora- und Debian-Linux-Distributionen: um Projekten zu ermöglichen, ihren Ansatz für die Nummerierung von Releases gracefully zu ändern, ohne dass ein neues Release eine niedrigere Versionsnummer als frühere Releases zu haben scheint und ohne den Namen des Projekts ändern zu müssen.
Insbesondere die Unterstützung von Versions-Epochen ermöglicht es einem Projekt, das zuvor datumsbasierte Versionierung verwendete, zur semantischen Versionierung zu wechseln, indem eine neue Versions-Epoche angegeben wird.
Das Zeichen ! wurde gewählt, um eine Epochenversion zu trennen, anstatt das Zeichen :, das in anderen Systemen üblicherweise verwendet wird, da : kein gültiges Zeichen in einem Windows-Verzeichnisnamen ist.
Hinzufügen von direkten Referenzen
Direkte Verweise werden als "Escape-Klausel" hinzugefügt, um unübersichtliche reale Situationen zu bewältigen, die sich nicht sauber in das Standardverteilungsmodell einfügen lassen. Dies schließt Abhängigkeiten von unveröffentlichten Software für den internen Gebrauch ein, sowie die Handhabung komplexerer Kompatibilitätsprobleme, die beim Umwickeln von Drittanbieter-Bibliotheken als C-Erweiterungen auftreten können (dies ist von besonderem Interesse für die wissenschaftliche Gemeinschaft).
Indexservern wird bewusst viel Freiheit eingeräumt, direkte Verweise abzulehnen, da sie in erster Linie als Werkzeug für Integratoren und nicht für Publisher gedacht sind. PyPI durchläuft derzeit insbesondere den Prozess der *Beseitigung* von Abhängigkeiten von externen Verweisen, da unzuverlässige externe Dienste die Installationsvorgänge verlangsamen und die scheinbare Zuverlässigkeit von PyPI selbst verringern.
Hinzufügen von beliebiger Gleichheit
Beliebige Gleichheit wird als "Escape-Klausel" hinzugefügt, um den Fall zu behandeln, in dem jemand ein Projekt installieren muss, das eine nicht-konforme Version verwendet. Obwohl dieses PEP eine Kompatibilität von ~97% mit den bereits auf PyPI vorhandenen Versionen erreicht, gibt es immer noch ~3% der Versionen, die nicht analysiert werden können. Dieser Operator bietet eine einfache und effektive Möglichkeit, sie dennoch zu referenzieren, ohne die Semantik dessen "raten" zu müssen, was sie bedeuten (was erforderlich wäre, wenn etwas anderes als strenge zeichenkettenbasierte Gleichheit unterstützt würde).
Hinzufügen von lokalen Versionskennungen
Es ist eine Tatsache, dass Downstream-Integratoren oft Fehlerkorrekturen von Upstream in ältere Versionen zurückportieren müssen. Es ist einer der Dienste, für die Linux-Distributor bezahlt werden, und Anwendungsentwickler können auch Patches anwenden, die sie für gebündelte Abhängigkeiten benötigen.
Historisch gesehen war diese Praxis für plattformübergreifende sprachspezifische Verteilungswerkzeuge unsichtbar – die gemeldete "Version" in den Upstream-Metadaten ist dieselbe wie für den unveränderten Code. Diese Ungenauigkeit kann dann Probleme verursachen, wenn versucht wird, mit einer Mischung aus vom Integrator bereitgestelltem Code und unverändertem Upstream-Code zu arbeiten oder sogar nur zu identifizieren, welche Version der Software installiert ist.
Die Einführung von lokalen Versionsbezeichnern und "lokalen Versions-Labels" in das Versionierungsschema mit der entsprechenden Metadaten-Erweiterung python.integrator ermöglicht die genaue Darstellung dieser Art von Aktivität, was die Interoperabilität zwischen den Upstream-Tools und verschiedenen integrierten Plattformen verbessern sollte.
Das genau gewählte Schema ist weitgehend am bestehenden Verhalten von pkg_resources.parse_version und pkg_resources.parse_requirements orientiert, wobei der Hauptunterschied darin besteht, dass, während pkg_resources bei der Vergleich von Versionen für exakte Übereinstimmungen derzeit immer das Suffix berücksichtigt, das PEP erfordert, dass das lokale Versions-Label der Kandidatenversion ignoriert wird, wenn kein lokales Versions-Label in der Versionsspezifizierer-Klausel vorhanden ist. Darüber hinaus versucht das PEP nicht, eine Struktur auf die lokalen Versions-Labels zu erzwingen (abgesehen von der Beschränkung des Satzes zulässiger Zeichen und der Definition ihrer Reihenfolge).
Diese Änderung soll sicherstellen, dass eine vom Integrator bereitgestellte Version wie pip 1.5+1 oder pip 1.5+1.git.abc123de immer noch einen Versionsspezifizierer wie pip>=1.5 erfüllt.
Das Pluszeichen wird hauptsächlich zur Lesbarkeit lokaler Versionsbezeichner gewählt. Es wurde anstelle des Bindestrichs gewählt, um zu verhindern, dass pkg_resources.parse_version es als Vorabversion interpretiert, was wichtig ist, um eine erfolgreiche Migration zum neuen, strukturierteren Versionierungsschema zu ermöglichen. Das Pluszeichen wurde anstelle einer Tilde gewählt, da die Tilde in Debians Versionssortieralgorithmus eine besondere Bedeutung hat.
Bereitstellung expliziter Versionsnormalisierungsregeln
Historisch gesehen war der De-facto-Standard für die Analyse von Versionen in Python der Befehl pkg_resources.parse_version aus dem setuptools-Projekt. Dieser versucht nicht, *irgendeine* Version abzulehnen, sondern versucht, aus dem, was er erhält, etwas Sinnvolles zu machen, mit unterschiedlichem Erfolg. Er hat ein paar einfache Regeln, aber ansonsten stützt er sich mehr oder weniger stark auf den String-Vergleich.
Die in diesem PEP bereitgestellten Normalisierungsregeln dienen hauptsächlich dazu, entweder die Kompatibilität mit pkg_resources.parse_version zu erhöhen, insbesondere in dokumentierten Anwendungsfällen wie rev, r, pre usw., oder etwas Sinnvolleres mit bereits auf PyPI vorhandenen Versionen zu tun.
Alle möglichen Normalisierungsregeln wurden danach abgewogen, ob sie *wahrscheinlich* Mehrdeutigkeiten verursachen würden (z. B. während jemand ein Schema entwickeln könnte, bei dem v1.0 und 1.0 als unterschiedliche Releases gelten, ist die Wahrscheinlichkeit, dass jemand dies tatsächlich tut, geschweige denn in einem bemerkenswerten Umfang, ziemlich gering). Sie wurden auch danach abgewogen, wie pkg_resources.parse_version einen bestimmten Versionsstring behandelte, insbesondere in Bezug auf die Sortierung. Schließlich wurde jede Regel gegen die Arten von zusätzlichen Versionen abgewogen, die sie zuließ, wie "hässlich" diese Versionen aussahen, wie schwer sie zu parsen waren (sowohl mental als auch mechanisch) und wie viel zusätzliche Kompatibilität sie bringen würde.
Die Breite der möglichen Normalisierungen wurde auf Dinge beschränkt, die leicht als Teil des Parsens der Version implementiert werden können und nicht als Vor-Parsing-Transformationen, die auf die Versionen angewendet werden. Dies geschah, um die Nebenwirkungen jeder Transformation zu begrenzen, da einfache Suchen-und-Ersetzen-artige Transformationen die Wahrscheinlichkeit von mehrdeutigen oder "Schrott"-Versionen erhöhen.
Für eine ausführliche Diskussion der verschiedenen Arten von Normalisierungen, die in Betracht gezogen wurden, siehe den Proof of Concept für PEP 440 innerhalb von pip [5].
Zulassen von Unterstrichen in der Normalisierung
Es gibt nicht viele Projekte auf PyPI, die einen Unterstrich (_) in der Versionszeichenkette verwenden. Dieses PEP erlaubt jedoch seine Verwendung überall dort, wo ein Bindestrich (-) akzeptabel ist. Der Grund dafür ist, dass das Wheel-Normalisierungsschema vorsieht, dass der Bindestrich (-) zu einem Unterstrich (_) normalisiert wird, um das Parsen des Dateinamens zu erleichtern.
Zusammenfassung der Änderungen an PEP 440
Die folgenden Änderungen wurden an diesem PEP aufgrund von Feedback vorgenommen, das nach der Veröffentlichung der ersten Referenzimplementierung in setuptools 8.0 und pip 6.0 erhalten wurde.
- Die exklusiven geordneten Vergleiche wurden aktualisiert, um nicht mehr implizit
!=V.*zu implizieren, was als überraschendes Verhalten erachtet wurde, das zu genau zu beschreiben zu schwierig war. Stattdessen werden die exklusiven geordneten Vergleiche einfach das Treffen von Prä-Releases, Post-Releases und lokalen Versionen der angegebenen Version verbieten (es sei denn, die angegebene Version ist selbst eine Prä-Releases, Post-Releases oder lokale Version). Für eine ausführliche Diskussion siehe die Threads auf distutils-sig [6] [7]. - Die normalisierte Form für Release Candidates wurde von 'c' auf 'rc' aktualisiert. Diese Änderung basierte auf Benutzerfeedback, das nach der Anwendung von Normalisierungen auf die Release-Metadaten durch setuptools 8.0 bei der Vorbereitung von Paketen für die Veröffentlichung auf PyPI erhalten wurde [8].
- Der PEP-Text und der Regex für
is_canonicalwurden aktualisiert, um explizit zu machen, dass numerische Komponenten speziell als Sequenzen von ASCII-Ziffern dargestellt werden müssen, nicht als beliebige Unicode [Nd] Codepunkte. Dies war zuvor durch den Versions-Parsing-Regex in Anhang B impliziert, aber nicht explizit angegeben [10].
Referenzen
Der erste Versuch eines standardisierten Versionsschemas sowie die Begründungen für die Notwendigkeit eines solchen Standards finden sich in PEP 386.
Anhang A
Richtlinien für Metadaten v2.0 im Vergleich zu setuptools
$ invoke check.pep440
Total Version Compatibility: 245806/250521 (98.12%)
Total Sorting Compatibility (Unfiltered): 45441/47114 (96.45%)
Total Sorting Compatibility (Filtered): 47057/47114 (99.88%)
Projects with No Compatible Versions: 498/47114 (1.06%)
Projects with Differing Latest Version: 688/47114 (1.46%)
Anhang B: Parsen von Versionszeichenfolgen mit regulären Ausdrücken
Wie bereits im Abschnitt Öffentliche Versionsbezeichner erwähnt, sollten veröffentlichte Versionsbezeichner das kanonische Format verwenden. Dieser Abschnitt liefert reguläre Ausdrücke, die verwendet werden können, um zu testen, ob eine Version bereits in dieser Form vorliegt, und wenn nicht, um die verschiedenen Komponenten zur anschließenden Normalisierung zu extrahieren.
Um zu testen, ob ein Versionsbezeichner im kanonischen Format vorliegt, können Sie die folgende Funktion verwenden
import re
def is_canonical(version):
return re.match(r'^([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*((a|b|rc)(0|[1-9][0-9]*))?(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$', version) is not None
Um die Komponenten eines Versionsbezeichners zu extrahieren, verwenden Sie den folgenden regulären Ausdruck (definiert durch das Projekt packaging)
VERSION_PATTERN = r"""
v?
(?:
(?:(?P<epoch>[0-9]+)!)? # epoch
(?P<release>[0-9]+(?:\.[0-9]+)*) # release segment
(?P<pre> # pre-release
[-_\.]?
(?P<pre_l>alpha|a|beta|b|preview|pre|c|rc)
[-_\.]?
(?P<pre_n>[0-9]+)?
)?
(?P<post> # post release
(?:-(?P<post_n1>[0-9]+))
|
(?:
[-_\.]?
(?P<post_l>post|rev|r)
[-_\.]?
(?P<post_n2>[0-9]+)?
)
)?
(?P<dev> # dev release
[-_\.]?
(?P<dev_l>dev)
[-_\.]?
(?P<dev_n>[0-9]+)?
)?
)
(?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
"""
_regex = re.compile(
r"^\s*" + VERSION_PATTERN + r"\s*$",
re.VERBOSE | re.IGNORECASE,
)
Urheberrecht
Dieses Dokument wurde gemeinfrei erklärt.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0440.rst
Zuletzt geändert: 2025-02-01 08:55:40 GMT