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

Python Enhancement Proposals

PEP 491 – Das Wheel Binärpaketformat 1.9

Autor:
Daniel Holth <dholth at gmail.com>
Discussions-To:
Distutils-SIG Liste
Status:
Verschoben
Typ:
Standards Track
Thema:
Packaging
Erstellt:
16-Apr-2015

Inhaltsverzeichnis

Zusammenfassung

Diese PEP beschreibt die zweite Version eines Built-Package-Formats für Python namens "Wheel". Wheel stellt ein Python-spezifisches, verschiebbares Paketformat bereit, das es den Leuten ermöglicht, Software schneller und vorhersagbarer zu installieren, als wenn sie jedes Mal aus dem Quellcode neu kompiliert wird.

Ein Wheel ist ein ZIP-formatiertes Archiv mit einem speziell formatierten Dateinamen und der Erweiterung .whl. Es enthält eine einzelne Distribution, fast so, wie sie gemäß PEP 376 mit einem bestimmten Installationsschema installiert würde. Einfache Wheels können auf sys.path entpackt und direkt verwendet werden, aber Wheels werden normalerweise mit einem spezialisierten Installer installiert.

Diese Version der Wheel-Spezifikation fügt Unterstützung für die Installation von Distributionen in viele verschiedene Verzeichnisse hinzu und fügt eine Möglichkeit hinzu, diese Dateien nach der Installation zu finden.

PEP Verschiebung

Diese PEP wird derzeit nicht aktiv verfolgt, da sich die Verbesserungen der Python-Paketierung derzeit auf den Paketbuild-Prozess konzentrieren, anstatt das Binärarchivformat auf zusätzliche Anwendungsfälle auszuweiten.

Einige spezifische Punkte, die bei der Wiederaufnahme der Arbeit an dieser PEP in Zukunft behandelt werden sollen

  • Migration der offiziellen Wheel-Formatdefinition zu https://packaging.python.org/specifications/ (ähnlich wie PEP 566 für https://packaging.python.org/specifications/core-metadata/)
  • Aktualisierung der PEP selbst, um sich auf die *Änderungen* zwischen den beiden Versionen des Formats und die Begründung für diese Änderungen zu konzentrieren, anstatt alle unveränderten Informationen aus PEP 427 zu wiederholen
  • Klarstellung, dass die PEP absichtlich so geschrieben ist, dass bestehende Installer mit der Spezifikation konform sind, wenn sie bestehende Installationsschemadefinitionen verwenden, und gleichzeitig die Erstellung neuer Installationsschemadefinitionen ermöglicht, die die reichhaltigere Kategorisierungsschema für den Inhalt des Binärarchivs nutzen

Begründung

Wheel 1.0 ist am besten darin, Dateien in site-packages und einige andere von distutils spezifizierte Orte zu installieren, aber Benutzer möchten Dateien aus einer einzelnen Distribution in viele Verzeichnisse installieren – vielleicht getrennte Orte für Dokumentation, Daten und Code. Leider sind sich nicht alle einig, wo diese Installationsorte relativ zum Stammverzeichnis liegen sollen. Diese Version des Formats fügt viele weitere Kategorien hinzu, von denen jede an einem anderen Ziel basierend auf der Richtlinie installiert werden kann. Da es auch wichtig sein kann, die installierten Dateien zur Laufzeit zu finden, fügt diese Version des Formats auch eine Möglichkeit hinzu, die installierten Pfade so aufzuzeichnen, dass sie von der installierten Software gelesen werden können.

Details

Installation eines Wheels 'distribution-1.0-py32-none-any.whl'

Die Wheel-Installation besteht notionsweise aus zwei Phasen

  • Entpacken.
    1. Parsen von distribution-1.0.dist-info/WHEEL.
    2. Prüfen, ob der Installer mit Wheel-Version kompatibel ist. Warnen, wenn die Nebenversion größer ist, abbrechen, wenn die Hauptversion größer ist.
    3. Wenn Root-Is-Purelib == 'true', das Archiv in purelib (site-packages) entpacken.
    4. Andernfalls das Archiv in platlib (site-packages) entpacken.
  • Verteilung.
    1. Das entpackte Archiv enthält distribution-1.0.dist-info/ und (falls vorhanden) distribution-1.0.data/.
    2. Verschieben jedes Unterverzeichnisses von distribution-1.0.data/ auf seinen Zielpfad. Jedes Unterverzeichnis von distribution-1.0.data/ ist ein Schlüssel in einem Wörterbuch von Zielverzeichnissen, wie z. B. distribution-1.0.data/(purelib|platlib|headers|scripts|data).
    3. Skripte, die mit #!python beginnen, aktualisieren, um auf den richtigen Interpreter zu verweisen. (Hinweis: Python-Skripte werden normalerweise über Paketmetadaten behandelt und nicht wortwörtlich in Wheel enthalten.)
    4. Aktualisieren von distribution-1.0.dist.info/RECORD mit den installierten Pfaden.
    5. Wenn leer, das Verzeichnis distribution-1.0.data entfernen.
    6. Kompilieren aller installierten .py zu .pyc. (Deinstallierer sollten intelligent genug sein, .pyc zu entfernen, auch wenn es nicht in RECORD aufgeführt ist.)

In der Praxis werden Installer normalerweise Dateien direkt aus dem Archiv an ihre Ziele extrahieren, ohne ein temporäres Verzeichnis distribution-1.0.data/ zu erstellen.

Dateiformat

Dateinamenskonvention

Der Wheel-Dateiname lautet {distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl.

distribution
Distributionsname, z. B. 'django', 'pyramid'.
version
Distributionsversion, z. B. 1.0.
build tag
Optionaler Build-Nummer. Muss mit einer Ziffer beginnen. Ein Tie-Breaker, wenn zwei Wheels dieselbe Version haben. Sortierung als leere Zeichenkette, wenn nicht angegeben, dann Sortierung der anfänglichen Ziffern als Zahl und des Rests lexikographisch.
Sprachimplementierungs- und Versions-Tag
z. B. 'py27', 'py2', 'py3'.
abi tag
z. B. 'cp33m', 'abi3', 'none'.
platform tag
z. B. 'linux_x86_64', 'any'.

Beispielsweise ist distribution-1.0-1-py27-none-any.whl der erste Build eines Pakets namens 'distribution' und ist kompatibel mit Python 2.7 (beliebige Python 2.7-Implementierung), mit keiner ABI (reines Python) auf jeder CPU-Architektur.

Die letzten drei Komponenten des Dateinamens vor der Erweiterung werden als "Kompatibilitätstags" bezeichnet. Die Kompatibilitätstags geben die grundlegenden Interpreter-Anforderungen des Pakets an und sind in PEP 425 detailliert beschrieben.

Escaping und Unicode

Jede Komponente des Dateinamens wird durch Ersetzen von Folgen von nicht-alphanumerischen Zeichen durch einen Unterstrich _ escaped.

re.sub("[^\w\d.]+", "_", distribution, re.UNICODE)

Der Archivdateiname ist Unicode. Die Packaging-Tools unterstützen möglicherweise nur ASCII-Paketnamen, aber Unicode-Dateinamen werden in dieser Spezifikation unterstützt.

Die Dateinamen *innerhalb* des Archivs werden als UTF-8 kodiert. Obwohl einige gängige ZIP-Clients UTF-8-Dateinamen nicht richtig anzeigen, wird die Kodierung sowohl von der ZIP-Spezifikation als auch von Pythons zipfile unterstützt.

Dateiinhalte

Der Inhalt einer Wheel-Datei, wobei {distribution} durch den Namen des Pakets ersetzt wird, z. B. beaglevote, und {version} durch seine Version ersetzt wird, z. B. 1.0.0, besteht aus

  1. /, dem Stammverzeichnis des Archivs, enthält alle Dateien, die in purelib oder platlib installiert werden sollen, wie in WHEEL angegeben. purelib und platlib sind normalerweise beide site-packages.
  2. {distribution}-{version}.dist-info/ enthält Metadaten.
  3. {distribution}-{version}.data/ enthält ein Unterverzeichnis für jeden nicht leeren Install-Schema-Schlüssel, der noch nicht abgedeckt ist, wobei der Verzeichnisname ein Index in einem Wörterbuch von Installationspfaden ist (z. B. data, scripts, include, purelib, platlib).
  4. Python-Skripte müssen in scripts erscheinen und exakt mit b'#!python' beginnen, um die Generierung von Skript-Wrappern und das Umschreiben von #!python zur Installationszeit zu erhalten. Sie können jede oder keine Erweiterung haben.
  5. {distribution}-{version}.dist-info/METADATA sind Metadaten im Format Version 1.1 oder höher.
  6. {distribution}-{version}.dist-info/WHEEL sind Metadaten über das Archiv selbst im gleichen grundlegenden Schlüssel:Wert-Format.
    Wheel-Version: 1.9
    Generator: bdist_wheel 1.9
    Root-Is-Purelib: true
    Tag: py2-none-any
    Tag: py3-none-any
    Build: 1
    Install-Paths-To: wheel/_paths.py
    Install-Paths-To: wheel/_paths.json
    
  7. Wheel-Version ist die Versionsnummer der Wheel-Spezifikation.
  8. Generator ist der Name und optional die Version der Software, die das Archiv erstellt hat.
  9. Root-Is-Purelib ist true, wenn das Stammverzeichnis des Archivs in purelib installiert werden soll; andernfalls soll der Stamm in platlib installiert werden.
  10. Tag sind die erweiterten Kompatibilitätstags des Wheels; im Beispiel würde der Dateiname py2.py3-none-any enthalten.
  11. Build ist die Build-Nummer und wird weggelassen, wenn keine Build-Nummer vorhanden ist.
  12. Install-Paths-To ist ein Ort, der *relativ zum Archiv* liegt und mit den Installationszeitenpfaden jeder Kategorie im Installationsschema überschrieben wird. Siehe den Abschnitt über Installationspfade. Kann 0 oder mehr Mal vorkommen.
  13. Ein Wheel-Installer sollte warnen, wenn Wheel-Version höher ist als die vom Installer unterstützte Version, und muss abbrechen, wenn Wheel-Version eine höhere Hauptversion hat als die vom Installer unterstützte Version.
  14. Wheel, als Installationsformat, das über mehrere Python-Versionen hinweg funktionieren soll, enthält im Allgemeinen keine .pyc-Dateien.
  15. Wheel enthält weder setup.py noch setup.cfg.
Das .dist-info Verzeichnis
  1. Wheel .dist-info Verzeichnisse enthalten mindestens METADATA, WHEEL und RECORD.
  2. METADATA sind die Paketmetadaten, im gleichen Format wie PKG-INFO, das im Stammverzeichnis von sdists gefunden wird.
  3. WHEEL sind die Wheel-Metadaten, spezifisch für einen Build des Pakets.
  4. RECORD ist eine Liste von (fast) allen Dateien im Wheel und ihren sicheren Hashes. Im Gegensatz zu PEP 376 muss jede Datei außer RECORD, die keinen Hash von sich selbst enthalten kann, ihren Hash enthalten. Der Hash-Algorithmus muss sha256 oder besser sein; insbesondere sind md5 und sha1 nicht erlaubt, da signierte Wheel-Dateien auf die starken Hashes in RECORD angewiesen sind, um die Integrität des Archivs zu überprüfen.
  5. PEP 376s INSTALLER und REQUESTED sind nicht im Archiv enthalten.
  6. RECORD.jws wird für digitale Signaturen verwendet. Es wird in RECORD nicht erwähnt.
  7. RECORD.p7s ist als Gefälligkeit für jeden erlaubt, der S/MIME-Signaturen zur Sicherung seiner Wheel-Dateien bevorzugt. Es wird in RECORD nicht erwähnt.
  8. Während der Extraktion verifizieren Wheel-Installer alle Hashes in RECORD gegen die Dateiinhalte. Abgesehen von RECORD und seinen Signaturen schlägt die Installation fehl, wenn eine Datei im Archiv nicht sowohl in RECORD erwähnt als auch korrekt gehasht ist.
Das .data Verzeichnis

Jede Datei, die nicht normalerweise in site-packages installiert wird, kommt in das .data-Verzeichnis und wird wie das .dist-info-Verzeichnis benannt, aber mit der Erweiterung .data/

distribution-1.0.dist-info/

distribution-1.0.data/

Das .data-Verzeichnis enthält Unterverzeichnisse mit den Skripten, Headern, Dokumentationen usw. der Distribution. Während der Installation werden die Inhalte dieser Unterverzeichnisse auf ihre Zielpfade verschoben.

Wenn ein Unterverzeichnis im Installationsschema nicht gefunden wird, sollte der Installer eine Warnung ausgeben, und es sollte unter distribution-1.0.data/... installiert werden, als ob das Paket von einem Standard-Entpackungsprogramm entpackt worden wäre.

Installationspfade

Zusätzlich zu den distutils-Installationspfaden enthält Wheel jetzt die aufgelisteten Kategorien, die auf GNU Autotools basieren. Dieses erweiterte Schema sollte Installern helfen, Systemrichtlinien zu implementieren, aber Installer können jede Kategorie an jedem Ort wurzeln.

Ein UNIX-Installationsschema könnte die Kategorien wie folgt auf ihre Installationspfade abbilden:

{
    'bindir': '$eprefix/bin',
    'sbindir': '$eprefix/sbin',
    'libexecdir': '$eprefix/libexec',
    'sysconfdir': '$prefix/etc',
    'sharedstatedir': '$prefix/com',
    'localstatedir': '$prefix/var',
    'libdir': '$eprefix/lib',
    'static_libdir': r'$prefix/lib',
    'includedir': '$prefix/include',
    'datarootdir': '$prefix/share',
    'datadir': '$datarootdir',
    'mandir': '$datarootdir/man',
    'infodir': '$datarootdir/info',
    'localedir': '$datarootdir/locale',
    'docdir': '$datarootdir/doc/$dist_name',
    'htmldir': '$docdir',
    'dvidir': '$docdir',
    'psdir': '$docdir',
    'pdfdir': '$docdir',
    'pkgdatadir': '$datadir/$dist_name'
}

Wenn ein Paket seine Dateien zur Laufzeit finden muss, kann es anfordern, dass diese von dem Installer in eine angegebene Datei oder Dateien geschrieben werden *und* in denselben Dateien innerhalb des Archivs enthalten sind, relativ zu ihrem Speicherort innerhalb des Archivs (damit ein Wheel auch korrekt installiert wird, wenn es mit einem Standard-Entpackungsprogramm entpackt wird oder vielleicht gar nicht entpackt wird).

Wenn die WHEEL-Metadaten diese Felder enthalten

Install-Paths-To: wheel/_paths.py
Install-Paths-To: wheel/_paths.json

Dann ersetzt der Wheel-Installer, wenn er dabei ist, wheel/_paths.py aus dem Archiv zu entpacken, diese durch die tatsächlichen Pfade, die zur Installationszeit verwendet werden. Die Pfade können absolut sein oder relativ zu der generierten Datei.

Wenn der Dateiname mit .py endet, wird ein Python-Skript geschrieben. Das Skript MUSS ausgeführt werden, um die Pfade zu erhalten, aber es wird wahrscheinlich so aussehen:

data='../wheel-0.26.0.dev1.data/data'
headers='../wheel-0.26.0.dev1.data/headers'
platlib='../wheel-0.26.0.dev1.data/platlib'
purelib='../wheel-0.26.0.dev1.data/purelib'
scripts='../wheel-0.26.0.dev1.data/scripts'
# ...

Wenn der Dateiname mit .json endet, wird ein JSON-Dokument geschrieben.

{ "data": "../wheel-0.26.0.dev1.data/data", ... }

Nur die von einem bestimmten Wheel tatsächlich verwendeten Kategorien müssen in diese Datei geschrieben werden.

Diese Dateien sind so konzipiert, dass sie an einem Ort geschrieben werden, der von dem installierten Paket gefunden werden kann, ohne eine Abhängigkeit von einer Packaging-Bibliothek einzuführen.

Signierte Wheel-Dateien

Wheel-Dateien enthalten ein erweitertes RECORD, das digitale Signaturen ermöglicht. PEP 376s RECORD wird geändert, um einen sicheren Hash digestname=urlsafe_b64encode_nopad(digest) (urlsafe base64-Kodierung ohne nachfolgende = Zeichen) als zweite Spalte anstelle einer md5sum zu enthalten. Alle möglichen Einträge werden gehasht, einschließlich aller generierten Dateien wie .pyc-Dateien, aber nicht RECORD, das seinen eigenen Hash nicht enthalten kann. Zum Beispiel:

file.py,sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\_pNh2yI,3144
distribution-1.0.dist-info/RECORD,,

Die Signaturdatei(en) RECORD.jws und RECORD.p7s werden in RECORD überhaupt nicht erwähnt, da sie erst nach der Generierung von RECORD hinzugefügt werden können. Jede andere Datei im Archiv muss einen korrekten Hash in RECORD haben, sonst schlägt die Installation fehl.

Wenn JSON Web Signatures verwendet werden, werden eine oder mehrere JSON Web Signature JSON Serialization (JWS-JS) Signaturen in einer Datei RECORD.jws neben RECORD gespeichert. JWS wird verwendet, um RECORD zu signieren, indem der SHA-256-Hash von RECORD als JSON-Payload der Signatur aufgenommen wird.

{ "hash": "sha256=ADD-r2urObZHcxBW3Cr-vDCu5RJwT4CaRTHiFmbcIYY" }

(Der Hash-Wert ist im gleichen Format wie in RECORD.)

Wenn RECORD.p7s verwendet wird, muss es eine getrennte Signatur von RECORD im S/MIME-Format enthalten.

Ein Wheel-Installer muss zwar keine digitalen Signaturen verstehen, aber er MUSS die Hashes in RECORD gegen die extrahierten Dateiinhalte verifizieren. Wenn der Installer Dateihashes gegen RECORD prüft, muss ein separater Signaturprüfer nur feststellen, dass RECORD mit der Signatur übereinstimmt.

Siehe

Vergleich zu .egg

  1. Wheel ist ein Installationsformat; Egg ist importierbar. Wheel-Archive müssen keine .pyc enthalten und sind weniger an eine bestimmte Python-Version oder Implementierung gebunden. Wheel kann (reine Python-)Pakete installieren, die mit früheren Python-Versionen erstellt wurden, sodass Sie nicht immer auf den Paketierer warten müssen, bis er aufholt.
  2. Wheel verwendet .dist-info-Verzeichnisse; Egg verwendet .egg-info. Wheel ist mit der neuen Welt der Python-Paketierung und den neuen Konzepten, die sie mit sich bringt, kompatibel.
  3. Wheel hat eine reichhaltigere Dateinamenskonvention für die heutige Multi-Implementierungs-Welt. Ein einzelnes Wheel-Archiv kann seine Kompatibilität mit einer Reihe von Python-Sprachversionen und -Implementierungen, ABIs und Systemarchitekturen angeben. Historisch gesehen war die ABI spezifisch für eine CPython-Version, Wheel ist bereit für die stabile ABI.
  4. Wheel ist verlustfrei. Die erste Wheel-Implementierung bdist_wheel generiert immer egg-info und konvertiert es dann in ein .whl. Es ist auch möglich, bestehende Eggs und bdist_wininst-Distributionen zu konvertieren.
  5. Wheel ist versioniert. Jede Wheel-Datei enthält die Version der Wheel-Spezifikation und die Implementierung, die sie verpackt hat. Hoffentlich kann die nächste Migration einfach zu Wheel 2.0 erfolgen.
  6. Wheel ist eine Referenz auf das andere Python.

FAQ

Wheel definiert ein .data Verzeichnis. Soll ich all meine Daten dort hineinlegen?

Diese Spezifikation hat keine Meinung dazu, wie Sie Ihren Code organisieren sollen. Das .data-Verzeichnis ist lediglich ein Ort für alle Dateien, die nicht normalerweise innerhalb von site-packages oder auf der PYTHONPATH installiert werden. Mit anderen Worten, Sie können weiterhin pkgutil.get_data(package, resource) verwenden, auch wenn *diese* Dateien normalerweise nicht in Wheels .data-Verzeichnis verteilt werden.

Warum enthält Wheel angehängte Signaturen?

Angehängte Signaturen sind praktischer als getrennte Signaturen, da sie mit dem Archiv reisen. Da nur die einzelnen Dateien signiert werden, kann das Archiv neu komprimiert werden, ohne die Signatur ungültig zu machen, oder einzelne Dateien können verifiziert werden, ohne das gesamte Archiv herunterladen zu müssen.

Warum erlaubt Wheel JWS-Signaturen?

Die JOSE-Spezifikationen, zu denen JWS gehört, sind so konzipiert, dass sie leicht zu implementieren sind, eine Funktion, die auch eines der Hauptentwicklungsziele von Wheel ist. JWS liefert eine nützliche, prägnante reine Python-Implementierung.

Warum erlaubt Wheel auch S/MIME-Signaturen?

S/MIME-Signaturen sind für Benutzer zulässig, die vorhandene Public-Key-Infrastrukturen mit Wheel nutzen müssen oder wollen.

Signierte Pakete sind nur ein grundlegender Baustein in einem sicheren Paket-Update-System. Wheel stellt nur den Baustein bereit.

Was hat es mit "purelib" vs. "platlib" auf sich?

Wheel behält die Unterscheidung "purelib" vs. "platlib" bei, die auf einigen Plattformen wichtig ist. Zum Beispiel installiert Fedora reine Python-Pakete nach '/usr/lib/pythonX.Y/site-packages' und plattformabhängige Pakete nach '/usr/lib64/pythonX.Y/site-packages'.

Ein Wheel mit "Root-Is-Purelib: false" mit allen seinen Dateien in {name}-{version}.data/purelib ist äquivalent zu einem Wheel mit "Root-Is-Purelib: true" mit denselben Dateien im Stammverzeichnis, und es ist zulässig, Dateien sowohl in der "purelib"- als auch in der "platlib"-Kategorie zu haben.

In der Praxis sollte ein Wheel nur eine der beiden Optionen "purelib" oder "platlib" haben, je nachdem, ob es sich um reines Python handelt oder nicht, und diese Dateien sollten sich im Stammverzeichnis befinden, wobei die entsprechende Einstellung für "Root-is-purelib" angegeben ist.

Ist es möglich, Python-Code direkt aus einer Wheel-Datei zu importieren?

Technisch gesehen, aufgrund der Kombination aus Unterstützung der Installation durch einfache Extraktion und der Verwendung eines Archivformats, das mit zipimport kompatibel ist, unterstützt eine Teilmenge von Wheel-Dateien die direkte Platzierung auf sys.path. Allerdings wird die tatsächliche Nutzung dieses Verhaltens, obwohl es eine natürliche Folge des Formatdesigns ist, im Allgemeinen nicht empfohlen.

Erstens ist Wheel *hauptsächlich als Distributionsformat konzipiert*, so dass das Überspringen des Installationsschritts auch bedeutet, bewusst auf Funktionen zu verzichten, die eine vollständige Installation voraussetzen (wie z. B. die Verwendung von Standardwerkzeugen wie pip und virtualenv, um Abhängigkeiten zu erfassen und zu verwalten, die ordnungsgemäß für Prüfungs- und Sicherheitsupdatezwecke nachverfolgt werden können, oder die vollständige Integration mit der Standard-Build-Maschinerie für C-Erweiterungen durch Veröffentlichung von Header-Dateien an der richtigen Stelle).

Zweitens, obwohl einige Python-Software so geschrieben ist, dass sie direkt aus einem ZIP-Archiv ausgeführt werden kann, ist es immer noch üblich, dass Code so geschrieben wird, dass er eine vollständige Installation voraussetzt. Wenn diese Annahme durch den Versuch, die Software aus einem ZIP-Archiv auszuführen, gebrochen wird, können die Fehler oft obskur und schwer zu diagnostizieren sein (insbesondere wenn sie in Drittanbieter-Bibliotheken auftreten). Die beiden häufigsten Problemquellen dabei sind die Tatsache, dass das Importieren von C-Erweiterungen aus einem ZIP-Archiv von CPython *nicht* unterstützt wird (da dies auf keiner Plattform direkt von der dynamischen Ladeinfrastruktur unterstützt wird) und dass bei der Ausführung aus einem ZIP-Archiv das Attribut __file__ nicht mehr auf einen gewöhnlichen Dateisystempfad verweist, sondern auf eine Pfadkombination, die sowohl den Speicherort des ZIP-Archivs im Dateisystem als auch den relativen Pfad zum Modul innerhalb des Archivs umfasst. Selbst wenn Software intern korrekt die abstrakten Ressourcen-APIs verwendet, kann die Schnittstelle mit externen Komponenten immer noch die Verfügbarkeit einer tatsächlichen Datei auf der Festplatte erfordern.

Wie Metaklassen, Monkeypatching und Metapath-Importer: Wenn Sie sich nicht sicher sind, ob Sie diese Funktion nutzen müssen, brauchen Sie sie mit ziemlicher Sicherheit nicht. Wenn Sie sich trotzdem dafür entscheiden, beachten Sie, dass viele Projekte eine Fehlerbehebung benötigen, die mit einem vollständig installierten Paket reproduziert wurde, bevor sie als echter Fehler akzeptiert wird.

Anhang

Beispiel für urlsafe-base64-nopad-Implementierung

# urlsafe-base64-nopad for Python 3
import base64

def urlsafe_b64encode_nopad(data):
    return base64.urlsafe_b64encode(data).rstrip(b'=')

def urlsafe_b64decode_nopad(data):
    pad = b'=' * (4 - (len(data) & 3))
    return base64.urlsafe_b64decode(data + pad)

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

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