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

Python Enhancement Proposals

PEP 364 – Übergang zur Py3K Standardbibliothek

Autor:
Barry Warsaw <barry at python.org>
Status:
Zurückgezogen
Typ:
Standards Track
Erstellt:
01-März-2007
Python-Version:
2.6
Post-History:


Inhaltsverzeichnis

Zusammenfassung

PEP 3108 beschreibt die Reorganisation der Python-Standardbibliothek für die Veröffentlichung von Python 3.0. Dieses PEP beschreibt einen Mechanismus für den Übergang von der Python 2.x Standardbibliothek zur Python 3.0 Standardbibliothek. Dieser Übergang wird es Python-Programmierern ermöglichen und sie ermutigen, die neuen Namen der Python 3.0 Bibliothek ab Python 2.6 zu verwenden und gleichzeitig die alten Namen aus Gründen der Abwärtskompatibilität beizubehalten. Auf diese Weise kann ein Python-Programmierer vorwärtskompatiblen Code schreiben, ohne die Interoperabilität mit bestehenden Python-Programmen zu opfern.

Begründung

PEP 3108 präsentiert eine Begründung für die Reorganisation der Python-Standardbibliothek (stdlib). Dem Leser wird empfohlen, dieses PEP für Details darüber zu konsultieren, warum und wie die Bibliothek neu organisiert wird. Sollte PEP 3108 teilweise oder ganz akzeptiert werden, ist es vorteilhaft, Python-Programmierern zu ermöglichen, den Übergang zu den neuen stdlib-Modulnamen in Python 2.x zu beginnen, damit sie ab Python 2.6 vorwärtskompatiblen Code schreiben können.

Beachten Sie, dass PEP 3108 vorschlägt, einige "sinnlose alte Sachen" zu entfernen, d.h. Module, die nicht mehr nützlich oder notwendig sind. Das hier vorliegende PEP befasst sich nicht damit, da es keine vorwärtskompatiblen Probleme für zu entfernende Module gibt, außer dass die Verwendung solcher Module eingestellt werden muss.

Dieses PEP betrifft nur den Mechanismus, durch den Abbildungen von alten stdlib-Namen auf neue stdlib-Namen beibehalten werden. Bitte konsultieren Sie PEP 3108 für alle spezifischen Vorschläge zur Umbenennung von Modulen. Insbesondere sehen Sie den Abschnitt mit dem Titel Modules to Rename für Richtlinien zu den Abbildungen von alten auf neue Namen. Die wenigen Beispiele in diesem PEP dienen nur zur Veranschaulichung und sollten nicht für spezifische Umbenennungsempfehlungen verwendet werden.

Unterstützte Umbenennungen

Es gibt mindestens 4 Anwendungsfälle, die ausdrücklich von diesem PEP unterstützt werden

  • Einfache Umbenennungen von Paketen auf oberster Ebene, wie z.B. StringIO zu stringio;
  • Umbenennungen von Unterpaketen, bei denen der Paketname umbenannt werden kann oder auch nicht, wie z.B. email.MIMEText zu email.mime.text;
  • Umbenennung von Erweiterungsmodulen, wie z.B. cStringIO zu cstringio;
  • Drittanbieter-Umbenennung von allen oben genannten.

Zwei Anwendungsfälle, die von diesem PEP unterstützt werden, beinhalten die Umbenennung von einfachen Modulen auf oberster Ebene, wie StringIO, sowie von Modulen innerhalb von Paketen, wie email.MIMEText.

Im ersteren Fall empfiehlt PEP 3108 derzeit, StringIO in stringio umzubenennen, gemäß den Empfehlungen von PEP 8.

Im letzteren Fall hat das mit Python 2.5 ausgelieferte Paket email 4.0 bereits email.MIMEText in email.mime.text umbenannt, obwohl dies auf eine einmalige, einzigartig hackelige Weise innerhalb des email-Pakets geschah. Der in diesem PEP beschriebene Mechanismus ist allgemein genug, um alle Modulumbenennungen zu handhaben, wodurch die Notwendigkeit des Python 2.5 Hacks entfällt (außer für die Abwärtskompatibilität mit früheren Python-Versionen).

Ein zusätzlicher Anwendungsfall ist die Unterstützung der Umbenennung von C-Erweiterungsmodulen. Solange der neue Name des C-Moduls importierbar ist, kann er auf den neuen Namen abgebildet werden. Z.B. cStringIO wird in cstringio umbenannt.

Auch die Umbenennung von Drittanbieterpaketen wird unterstützt, über verschiedene öffentliche Schnittstellen, auf die von jedem Python-Modul zugegriffen werden kann.

Abbildungen werden nicht rekursiv durchgeführt.

.mv-Dateien

Abbildungsdateien werden als .mv-Dateien bezeichnet; die Endung wurde gewählt, um an den Unix-Befehl mv(1) zu erinnern. Eine .mv-Datei ist eine einfache zeilenorientierte Textdatei. Alle Leerzeilen und Zeilen, die mit einem # beginnen, werden ignoriert. Alle anderen Zeilen müssen zwei durch Leerzeichen getrennte Felder enthalten. Das erste Feld ist der alte Modulname, das zweite Feld der neue Modulname. Beide Modulnamen müssen mit ihren vollständigen gepunkteten Pfadnamen angegeben werden. Hier ist eine Beispiel .mv-Datei aus Python 2.6

# Map the various string i/o libraries to their new names
StringIO    stringio
cStringIO   cstringio

.mv-Dateien können sich überall im Dateisystem befinden, und es gibt eine programmatische Schnittstelle, um sie zu parsen und die darin enthaltenen Abbildungen zu registrieren. Standardmäßig werden beim Start von Python alle .mv-Dateien im Paket oldlib gelesen und ihre Abbildungen automatisch registriert. Hier sind alle Modulumbenennungen für Python 2.x Standardbibliotheksmodule auf oberster Ebene anzugeben.

Implementierungsspezifikation

Dieser Abschnitt liefert die vollständige Spezifikation dafür, wie Modulumbenennungen in Python 2.x implementiert werden. Der zentrale Mechanismus beruht auf verschiedenen Import-Hooks, wie in PEP 302 beschrieben. Speziell sys.path_importer_cache, sys.path und sys.meta_path werden alle eingesetzt, um die notwendige Funktionalität bereitzustellen.

Wenn die Import-Maschinerie von Python initialisiert wird, wird das oldlib-Paket importiert. Innerhalb von oldlib gibt es eine Klasse namens OldStdlibLoader. Diese Klasse implementiert die PEP 302-Schnittstelle und wird automatisch mit null Argumenten instanziiert. Der Konstruktor liest alle .mv-Dateien aus dem oldlib-Paketverzeichnis und registriert automatisch alle in diesen .mv-Dateien gefundenen Abbildungen. So wird die Python 2.x Standardbibliothek umbenannt.

Die Klasse OldStdlibLoader sollte nicht von anderen Python-Modulen instanziiert werden. Stattdessen können Sie über die globale OldStdlibLoader-Instanz über die Instanz sys.stdlib_remapper auf die Instanz zugreifen. Verwenden Sie diese Instanz, wenn Sie programmatischen Zugriff auf die Abbildungsmaschine wünschen.

Ein wichtiges Implementierungsdetail: Wie von der PEP 302 API gefordert, wird ein magischer String zu sys.path und zu den Modul-`__path__`-Attributen hinzugefügt, um unseren Abbildungs-Loader einzuhaken. Dieser magische String ist derzeit <oldlib> und einige Änderungen am Python-Dateipfad `site.py` waren notwendig, um alle sys.path-Einträge, die mit < beginnen, als speziell zu behandeln. Insbesondere wird kein Versuch unternommen, sie in absolute Dateinamen umzuwandeln (da es sich nicht um Dateinamen handelt).

Damit die Abbildungs-Import-Hooks funktionieren, muss das Modul oder Paket physisch unter seinem neuen Namen liegen. Denn die Import-Hooks fangen nur Module ab, die noch nicht importiert sind und die nicht von den eingebauten Importregeln von Python importiert werden können. Wenn ein Modul also verschoben wurde, z.B. von Lib/StringIO.py nach Lib/stringio.py, und die .pyc-Datei des ersteren entfernt wurde, würde dies ohne den Remapper fehlschlagen.

import StringIO

Stattdessen wird mit dem Remapper dieser fehlschlagende Import abgefangen, der alte Name wird in den registrierten Abbildungen nachgeschlagen und in diesem Fall wird der neue Name stringio gefunden. Der Remapper versucht dann, den neuen Namen zu importieren, und wenn dies gelingt, bindet er das resultierende Modul sowohl unter dem alten als auch unter dem neuen Namen in sys.modules ein. Somit führt der obige Import zu Einträgen in sys.modules für 'StringIO' und 'stringio', und beide verweisen auf genau dasselbe Modulobjekt.

Beachten Sie, dass keine Möglichkeit vorgeschlagen wird, die Abbildungsmaschine zu deaktivieren, außer alle .mv-Dateien zu entfernen oder sie programmatisch in einem benutzerdefinierten Startcode zu löschen. In Python 3.0 werden die Abbildungen eliminiert, sodass nur die "neuen" Namen übrig bleiben.

Programmatische Schnittstelle

Mehrere Methoden werden zum Objekt sys.stdlib_remapper hinzugefügt, die Drittanbieterpakete verwenden können, um ihre eigenen Abbildungen zu registrieren. Beachten Sie jedoch, dass in allen Fällen eine und nur eine Abbildung von einem alten Namen auf einen neuen Namen existiert. Wenn zwei .mv-Dateien unterschiedliche Abbildungen für einen alten Namen enthalten oder wenn ein programmatischer Aufruf mit einem alten Namen erfolgt, der bereits abgebildet ist, geht die vorherige Abbildung verloren. Dies hat keine Auswirkungen auf bereits importierte Module.

Die folgenden Methoden sind auf dem Objekt sys.stdlib_remapper verfügbar

  • read_mv_file(filename) – Liest die angegebene Datei und registriert alle darin gefundenen Abbildungen.
  • read_directory_mv_files(dirname, suffix='.mv') – Listet das angegebene Verzeichnis auf und liest alle Dateien in diesem Verzeichnis, die die angegebene Endung (.mv standardmäßig) haben. Für jede geparste Datei werden alle darin gefundenen Abbildungen registriert.
  • set_mapping(oldname, newname) – Registriert eine neue Abbildung von einem alten Modulnamen auf einen neuen Modulnamen. Beide müssen der vollständige gepunktete Pfadname des Moduls sein. newname kann None sein, in diesem Fall wird jede bestehende Abbildung für oldname entfernt (es ist kein Fehler, wenn keine bestehende Abbildung vorhanden ist).
  • get_mapping(oldname, default=None) – Gibt den registrierten newname für den angegebenen oldname zurück. Wenn keine Abbildung registriert ist, wird default zurückgegeben.

Offene Fragen

  • Sollte es einen Befehlszeilenschalter und/oder eine Umgebungsvariable geben, um alle Abbildungen zu deaktivieren?
  • Sollen Abbildungen rekursiv erfolgen?
  • Sollen Paketverzeichnisse automatisch nach .mv-Dateien durchsucht werden, wenn die __init__.py des Pakets geladen wird? Dies würde es Paketen ermöglichen, einfach .mv-Dateien für ihre eigenen Umbenennungen einzubinden. Vergleichen Sie, was das email-Paket derzeit tun muss, wenn wir seine .mv-Datei im email-Paket statt im oldlib-Paket platzieren.
    # Expose old names
    import os, sys
    sys.stdlib_remapper.read_directory_mv_files(os.path.dirname(__file__))
    

    Ich denke, wir sollten automatisch das Verzeichnis eines Pakets auf .mv-Dateien durchsuchen, die es enthalten könnte.

Referenzimplementierung

Eine Referenzimplementierung in Form eines Patches gegen den aktuellen Stand des Python 2.6 svn-Trunk (zum Zeitpunkt der Abfassung) ist als SourceForge-Patch #1675334 [1] verfügbar. Beachten Sie, dass dieser Patch die Umbenennung von cStringIO in cstringio beinhaltet, dies jedoch hauptsächlich zu Illustrations- und Unit-Testzwecken geschieht. Sollte der Patch akzeptiert werden, könnten wir diese Änderung in andere PEP 3108-Änderungen aufteilen.

Referenzen


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

Zuletzt geändert: 2025-02-01 08:59:27 GMT