PEP 784 – Hinzufügen von Zstandard zur Standardbibliothek
- Autor:
- Emma Harper Smith <emma at python.org>
- Sponsor:
- Gregory P. Smith <greg at krypto.org>
- Discussions-To:
- Discourse thread
- Status:
- Final
- Typ:
- Standards Track
- Erstellt:
- 06-Apr-2025
- Python-Version:
- 3.14
- Post-History:
- 07-Apr-2025
- Resolution:
- 25-Apr-2025
Inhaltsverzeichnis
- Zusammenfassung
- Motivation
- Begründung
- Spezifikation
- Abwärtskompatibilität
- Sicherheitsimplikationen
- Wie man das lehrt
- Referenzimplementierung
- Abgelehnte Ideen
- Benennen Sie das Modul
zstdlibund erstellen Sie keinen neuencompression-Namensraum - Führen Sie ein experimentelles
_zstd-Paket in Python 3.14 ein - Führen Sie einen Standardbibliotheksnamensraum anstelle von
compressionein - Schließen Sie
zipfileundtarfileincompressionein - Schließen Sie
gzipnicht untercompressionein
- Benennen Sie das Modul
- Urheberrecht
Zusammenfassung
Zstandard ist ein weit verbreiteter, ausgereifter und hoch effizienter Komprimierungsstandard. Dieser PEP schlägt die Hinzufügung eines neuen Moduls zur Python-Standardbibliothek vor, das einen Python-Wrapper um Metas zstd-Bibliothek, die Standardimplementierung, enthält. Um Namenskollisionen mit PyPI-Paketen zu vermeiden und Python-Benutzern eine einheitliche Schnittstelle zu bieten, werden die Komprimierungsmodule in der Standardbibliothek unter einem compression.*-Paket zusammengefasst.
Motivation
CPython verfügt über Module für verschiedene Komprimierungsformate wie zlib (DEFLATE), gzip, bzip2 und lzma, die jeweils weit verbreitet sind. Die Einbeziehung beliebter Komprimierungsalgorithmen entspricht Pythons Philosophie „Batteries included“, die weit verbreitete und nützliche Standards und Dienstprogramme enthält. lzma ist das jüngste dieser Module, das in Python 3.3 hinzugefügt wurde.
Seitdem hat sich Zstandard zur modernen De-facto-Bevorzugungsbibliothek für hochleistungsfähige Komprimierung und Dekompression entwickelt, die hohe Komprimierungsraten bei angemessenem CPU- und Speicheraufwand erzielt. Zstandard erreicht eine wesentlich höhere Komprimierungsrate als bzip2 oder zlib (DEFLATE), während es wesentlich schneller dekomprimiert als LZMA.
Zstandard hat eine weite Verbreitung in vielen verschiedenen Bereichen des Computings erfahren. Die zahlreichen Hardware-Implementierungen zeigen ein langfristiges Engagement für Zstandard und die Erwartung, dass Zstandard die De-facto-Wahl für die Komprimierung für die kommenden Jahre bleiben wird. Dies wird ferner durch die IETF-Standardisierung von Zstandard in RFC 8478 belegt. Zstandard-Komprimierung ist auch in den Dateisystemen ZFS und Btrfs implementiert.
Die hoch effiziente Komprimierung von Zstandard hat andere moderne Komprimierungsformate wie brotli, lzo und ucl aufgrund seiner hohen Komprimierungseffizienz verdrängt. Während LZ4 immer noch in Szenarien mit sehr hohem Durchsatz verwendet wird, kann Zstandard auch in einigen dieser Kontexte verwendet werden. Obwohl die Einbeziehung von LZ4 außerhalb des Umfangs liegt, wäre es eine überzeugende zukünftige Ergänzung für den von diesem PEP eingeführten compression-Namensraum.
Es gibt mehrere Bindungen für Zstandard für Python auf PyPI, jede mit unterschiedlichen APIs und Auswahlmöglichkeiten, wie die zstd-Bibliothek gebunden werden soll. Ein Ziel bei der Einführung eines offiziellen Moduls in der Standardbibliothek ist die Reduzierung von Verwirrung für Python-Benutzer, die einfache Komprimierungs-/Dekomprimierungs-APIs für Zstandard wünschen. Die bestehenden Pakete können weiterhin erweiterte APIs anbieten oder Funktionen aus neueren Zstandard-Versionen integrieren.
Ein weiterer Grund für die Aufnahme von Zstandard-Unterstützung in die Standardbibliothek ist die Behebung eines seit langem offenen Problems (python/cpython#81276), das die Zstandard-Unterstützung im tarfile-Modul fordert. Dieses Problem hat die 5. höchste Anzahl an „Daumen hoch“ unter den offenen Problemen im CPython-Tracker und hat eine erhebliche Diskussion und Interesse hervorgerufen. Zusätzlich standardisiert das ZIP-Format eine Zstandard-Komprimierungsformat-ID, und die Integration mit dem zipfile-Modul würde das Öffnen von ZIP-Archiven mit Zstandard-Komprimierung ermöglichen. Die Referenzimplementierung für diesen PEP enthält eine Integration mit den Modulen zipfile, tarfile und shutil.
Zstandard-Komprimierung könnte auch verwendet werden, um Python Wheel-Pakete kleiner und erheblich schneller zu installieren. Anaconda fand eine beachtliche Beschleunigung, als Zstandard für das Conda-Paketformat übernommen wurde.
Die Downloadgrößen von Conda werden um ca. 30-40 % reduziert und die Extraktion ist deutlich schneller. [...] Wir sehen eine Gesamtbeschleunigung von etwa dem 2,5-fachen, fast ausschließlich dank der dramatisch schnelleren Extraktionsgeschwindigkeit der Zstd-Komprimierung, die im neuen Dateiformat verwendet wird.
Zstandard hat eine signifikant höhere Komprimierungsrate im Vergleich zur bestehenden zlib-basierten Komprimierung von Wheels, laut lzbench, einem umfassenden Benchmark vieler verschiedener Komprimierungsbibliotheken und -formate. Obwohl dieser PEP keine Änderungen am Wheel-Format oder anderen Paketstandards vorschreibt, würde die Verfügbarkeit von Zstandard-Bindungen in der Standardbibliothek einem zukünftigen PEP ermöglichen, die Benutzererfahrung für Python-Wheel-Pakete zu verbessern.
Begründung
Einführung eines compression-Pakets
Sowohl die Importnamen zstd als auch zstandard werden von Projekten auf PyPI beansprucht. Um Benutzer bestehender Bindungen nicht zu beeinträchtigen, schlägt dieser PEP die Einführung eines neuen Namensraums für Komprimierungsbibliotheken, compression, vor. Dieser Name ist auf PyPI bereits für die Verwendung in der Standardbibliothek reserviert. Das neue Zstandard-Modul wird compression.zstd heißen. Andere Komprimierungsmodule werden im neuen compression-Paket neu exportiert.
Die Bereitstellung eines gemeinsamen Namensraums für Komprimierungsmodule hat mehrere Vorteile. Erstens reduziert es die Verwirrung der Benutzer darüber, wo sie Komprimierungsmodule finden können. Zweitens könnte das Top-Level-Modul compression Informationen darüber liefern, welche Komprimierungsformate verfügbar sind, ähnlich wie bei hashlib's algorithms_available. Wenn PEP 775 akzeptiert wird, könnte auch ein compression.algorithms_guaranteed bereitgestellt werden, das zlib auflistet. Schließlich verhindert ein compression-Namensraum zukünftige Probleme beim Zusammenführen anderer Komprimierungsformate in die Standardbibliothek. Neue Komprimierungsformate werden wahrscheinlich zuerst auf PyPI veröffentlicht, bevor sie in CPython integriert werden. Daher wird jeder neue Importname für ein Komprimierungsformat wahrscheinlich bereits beansprucht sein, wenn ein Modul für die Aufnahme in CPython in Betracht gezogen wird. Das Platzieren von Komprimierungsmodulen unter einem Paketpräfix verhindert Probleme mit potenziellen zukünftigen Namenskonflikten.
Code, der mit verschiedenen Python-Versionen kompatibel bleiben soll, kann das folgende Muster verwenden, um die Kompatibilität sicherzustellen
try:
from compression.lzma import LZMAFile
except ImportError:
from lzma import LZMAFile
Dies verwendet den neueren Importnamen, wenn verfügbar, und greift andernfalls auf den alten Namen zurück.
Implementierung basierend auf pyzstd
Die Implementierung für diesen PEP basiert auf dem pyzstd-Projekt. Dieses Projekt wurde ausgewählt, da der Code ursprünglich dafür geschrieben wurde, von Ma Lin in CPython eingebracht zu werden, der auch die heutige Implementierung des Ausgabepuffers in der Standardbibliothek schrieb. Das Projekt wurde inzwischen von Rogdham übernommen und auf PyPI veröffentlicht. Die APIs in pyzstd ähneln den APIs für andere Komprimierungsmodule in der Standardbibliothek wie bz2 und lzma.
Mindestens unterstützte Zstandard-Version
Die minimal unterstützte Zstandard-Version wurde als v1.4.5 gewählt, die im Mai 2020 veröffentlicht wurde. Diese Version wurde als Minimum gewählt, nachdem die verfügbaren Zstandard-Versionen in einer Reihe von Linux-Distribution-Paket-Repositories, einschließlich LTS-Versionen, geprüft wurden. Diese Versionswahl ist eher konservativ, um die Kompatibilität mit bestehenden LTS-Linux-Distributionen zu maximieren, aber eine neuere Zstandard-Version könnte wahrscheinlich gewählt werden, da neuere Python-Releases im Allgemeinen als Teil neuerer Distributions-Releases verpackt werden.
Spezifikation
Der compression-Namensraum
Ein neuer Namensraum für Komprimierungsmodule wird namens compression eingeführt. Das Top-Level-Modul für dieses Paket wird zunächst leer sein, aber eine Standard-API für die Interaktion mit Komprimierungsroutinen könnte zukünftig zum Top-Level hinzugefügt werden.
Das Modul compression.zstd
Ein neues Modul, compression.zstd, wird mit Zstandard-Komprimierungs-APIs eingeführt, die mit anderen Komprimierungsmodulen in der Standardbibliothek übereinstimmen, nämlich:
compress()/decompress()– APIs für einmalige Komprimierung oder DekomprimierungZstdFile/open()– APIs für die Interaktion mit Streams und dateiähnlichen ObjektenZstdCompressor/ZstdDecompressor– APIs für inkrementelle Komprimierung oder Dekomprimierung
Es wird auch einige Zstandard-spezifische Funktionalität enthalten:
ZstdDict/train_dict()/finalize_dict()– APIs für die Interaktion mit Zstandard-Wörterbüchern, die für die Komprimierung vieler kleiner Datenblöcke mit ähnlichen Daten nützlich sind
Optionale Abhängigkeit libzstd
Die libzstd-Bibliothek wird zu einer optionalen Abhängigkeit von CPython. Wenn die Bibliothek nicht verfügbar ist, ist das Modul compression.zstd nicht verfügbar. Dies wird unter Unix-Plattformen automatisch als Teil der normalen Build-Umgebungsprüfung gehandhabt.
Unter Windows wird libzstd zu den Quellabhängigkeiten hinzugefügt, die zum Erstellen von Bibliotheken verwendet werden, von denen CPython für Windows abhängt.
Andere Komprimierungsmodule
Neue Importnamen compression.lzma, compression.bz2, compression.gzip und compression.zlib werden in Python 3.14 eingeführt und exportieren den Inhalt der bestehenden Module lzma, bz2, gzip bzw. zlib. Die compression-Untermodule werden zukünftig die kanonischen Importnamen sein. Die Verwendung der neuen Komprimierungsnamen wird in der Python-Dokumentation gegenüber den ursprünglichen Top-Level-Modulnamen gefördert, wenn die Mindestanforderungen an die unterstützte Python-Version dies zulassen.
Das Modul _compression wird, da es als privat markiert ist, sofort in compression._common._streams umbenannt. Der neue Name wurde gewählt, da die aktuellen Inhalte des Moduls I/O-bezogene Helfer für Stream-APIs (z.B. LZMAFile) in Standardbibliotheks-Komprimierungsmodulen sind.
Abwärtskompatibilität
Dieser PEP führt keine rückwärtskompatiblen Änderungen ein. Es gibt derzeit keine Pläne, die bestehenden Komprimierungsmodule zu verwerfen oder zu entfernen. Jede Verwerfung oder Entfernung der bestehenden Module wird einer zukünftigen Entscheidung überlassen, wird aber nicht früher als 5 Jahre nach der Annahme dieses PEP erfolgen.
Sicherheitsimplikationen
Wie bei jedem neuen C-Code, insbesondere Code, der mit potenziell nicht vertrauenswürdigen Benutzereingaben arbeitet, bestehen Risiken von Speicherunsicherheiten. Der Autor plant, die Integration mit libfuzzer beizutragen, um das _zstd-Code-Fuzzing zu ermöglichen und sicherzustellen, dass er robust ist. Darüber hinaus gibt es eine Reihe von Tests, die die Komprimierungs- und Dekomprimierungsroutinen durchlaufen. Diese Tests werden ohne Fehler kompiliert, wenn sie mit AddressSanitizer kompiliert werden.
Die Übernahme einer neuen Abhängigkeit birgt ebenfalls immer Sicherheitsrisiken, aber die zstd-Bibliothek ist ausgereift, wird bei jedem Commit gefuzzed und nimmt am Bug-Bounty-Programm von Meta teil.
Wie man das lehrt
Die Dokumentation für das neue Modul befindet sich im Zweig der Referenzimplementierung. Die Dokumentation für bestehende Module wird ebenfalls aktualisiert, um auf die neuen Namen zu verweisen.
Referenzimplementierung
Die Referenzimplementierung enthält den _zstd C-Code, den compression.zstd-Code, Änderungen an tarfile, shutil und zipfile sowie Tests für jede neue API und Integration. Sie enthält auch die Neu-Exporte anderer Komprimierungsmodule.
Abgelehnte Ideen
Benennen Sie das Modul zstdlib und erstellen Sie keinen neuen compression-Namensraum
Eine Option anstelle der Erstellung eines neuen compression-Namensraums wäre die Suche nach einem anderen Namen, wie z.B. zstdlib, als Importnamen. Mehrere andere Namen wie zst, libzstd und zstdcomp wurden ebenfalls vorgeschlagen. In der Diskussion wurden die Namen als entweder zu fehleranfällig oder unintuitiv befunden. Darüber hinaus ist das Problem bestehender Importnamen wahrscheinlich für zukünftige Komprimierungsformate, die der Standardbibliothek hinzugefügt werden, weiterhin relevant. LZ4, ein gängiges Hochgeschwindigkeits-Komprimierungsformat, hat ein Paket auf PyPI, lz4, mit dem Importnamen lz4. Anstatt dieses Problem für jedes Komprimierungsformat einzeln zu lösen, ist es besser, es ein für alle Mal durch die Verwendung des bereits beanspruchten compression-Namensraums zu lösen.
Führen Sie ein experimentelles _zstd-Paket in Python 3.14 ein
Da dieser PEP nahe am Beta-Cutoff für neue Features für Python 3.14 veröffentlicht wurde, war ein Vorschlag, das Paket als privates Modul _zstd zu benennen, damit Paketierungswerkzeuge es früher nutzen können, aber keinen Namen festzulegen. Dies würde mehr Zeit für die Diskussion des endgültigen Modulnamens während des Entwicklungsfensters für 3.15 ermöglichen. Die Einführung eines privaten Moduls war jedoch nicht beliebt. Die Erwartungen und der Vertrag für die externe Nutzung eines privaten Moduls in der Standardbibliothek sind unklar.
Führen Sie einen Standardbibliotheksnamensraum anstelle von compression ein
Eine Alternative zu einem compression-Namensraum wäre die Einführung eines std-Namensraums für die gesamte Standardbibliothek. Dies wurde jedoch als zu bedeutende Änderung für 3.14 angesehen, ohne vereinbarte Semantik, Migrationspfade oder einen Namen für das Paket. Darüber hinaus könnte ein zukünftiger PEP, der einen std-Namensraum einführt, immer definieren, dass die compression-Untermodule in den std-Namensraum abgeflacht werden.
Schließen Sie zipfile und tarfile in compression ein
Komprimierung wird oft mit Archivierungswerkzeugen verwendet, daher ist es attraktiv, sowohl zipfile als auch tarfile unter dem compression-Namensraum zu platzieren. Komprimierung kann jedoch auch außerhalb von Archivierungswerkzeugen verwendet werden. Zum Beispiel können Netzwerkanfragen mit Gzip komprimiert werden. Darüber hinaus enthalten Formate wie tar selbst keine Komprimierung, sondern verlassen sich auf externe Komprimierung. Daher schlägt dieser PEP nicht vor, zipfile oder tarfile unter compression zu verschieben.
Schließen Sie gzip nicht unter compression ein
Das GZip-Format RFC definiert ein Format, das mehrere Blöcke und Metadaten über seinen Inhalt enthalten kann. Auf diese Weise ähnelt GZip stark Archivformaten wie ZIP und tar. Trotzdem wird GZip in der Anwendung oft eher als Komprimierungsformat denn als Archivformat behandelt. Betrachtet man, wie verschiedene Sprachen GZip klassifizieren, so ist der vorherrschende Trend, es als Komprimierungsformat und nicht als Archivierungsformat zu klassifizieren.
| Sprache | Komprimierung oder Archiv | Dokumentationslink |
|---|---|---|
| Golang | Komprimierung | https://pkg.go.dev/compress/gzip |
| Ruby | Komprimierung | https://docs.ruby-lang.de/en/master/Zlib/GzipFile.html |
| Rust | Komprimierung | https://github.com/rust-lang/flate2-rs |
| Haskell | Komprimierung | https://hackage.haskell.org/package/zlib |
| C# | Komprimierung | https://learn.microsoft.com/en-us/dotnet/api/system.io.compression.gzipstream |
| Java | Archiv | https://docs.oracle.com/javase/8/docs/api/java/util/zip/package-summary.html |
| NodeJS | Komprimierung | https://nodejs.org/api/zlib.html |
| Web-APIs | Komprimierung | https://developer.mozilla.org/en-US/docs/Web/API/Compression_Streams_API |
| PHP | Komprimierung | https://www.php.net/manual/en/function.gzcompress.php |
| Perl | Komprimierung | https://perldoc.perl.org/IO::Compress::Gzip |
Darüber hinaus konzentriert sich das gzip-Modul in Python hauptsächlich auf Inhalte mit einzelnen Blöcken und hat eine ähnliche API wie andere Komprimierungsmodule, was es gut für den compression-Namensraum geeignet macht.
Urheberrecht
Dieses Dokument wird in die Public Domain oder unter die CC0-1.0-Universal-Lizenz gestellt, je nachdem, welche Lizenz permissiver ist.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0784.rst
Zuletzt geändert: 2025-05-24 04:38:02 GMT