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

Python Enhancement Proposals

PEP 686 – UTF-8-Modus als Standard festlegen

Autor:
Inada Naoki <songofacandy at gmail.com>
Discussions-To:
Discourse thread
Status:
Akzeptiert
Typ:
Standards Track
Erstellt:
18. März 2022
Python-Version:
3.15
Post-History:
18. März 2022, 31. März 2022
Resolution:
Discourse-Nachricht

Inhaltsverzeichnis

Zusammenfassung

Diese PEP schlägt vor, den UTF-8-Modus standardmäßig zu aktivieren.

Mit dieser Änderung verwendet Python durchgängig UTF-8 für die Standardcodierung von Dateien, stdio und Pipes.

Motivation

UTF-8 wird zum De-facto-Standard für Textcodierung.

  • Die Standardcodierung von Python-Quelldateien ist UTF-8.
  • JSON, TOML, YAML verwenden UTF-8.
  • Die meisten Texteditoren, einschließlich Visual Studio Code und Windows Notepad, verwenden standardmäßig UTF-8.
  • Die meisten Websites und Textdaten im Internet verwenden UTF-8.
  • Und viele andere beliebte Programmiersprachen, darunter Node.js, Go, Rust und Java, verwenden standardmäßig UTF-8.

Die Umstellung der Standardcodierung auf UTF-8 erleichtert Python die Interoperabilität mit ihnen.

Zusätzlich vergessen viele Python-Entwickler, die Unix verwenden, dass die Standardcodierung plattformabhängig ist. Sie lassen die Angabe von encoding="utf-8" weg, wenn sie Textdateien lesen, die in UTF-8 codiert sind (z. B. JSON, TOML, Markdown und Python-Quelldateien). Inkonsistente Standardcodierung verursacht viele Fehler.

Spezifikation

UTF-8-Modus als Standard aktivieren

Python wird den UTF-8-Modus ab Python 3.15 standardmäßig aktivieren.

Benutzer können den UTF-8-Modus weiterhin deaktivieren, indem sie PYTHONUTF8=0 oder -X utf8=0 setzen.

locale.getencoding()

Da der UTF-8-Modus locale.getpreferredencoding(False) beeinflusst, benötigen wir eine API, um die Locale-Codierung unabhängig vom UTF-8-Modus abzurufen.

Zu diesem Zweck wird locale.getencoding() hinzugefügt. Diese gibt ebenfalls die Locale-Codierung zurück, ignoriert aber den UTF-8-Modus.

Wenn die Option warn_default_encoding angegeben ist, gibt locale.getpreferredencoding() eine EncodingWarning aus, ähnlich wie open() (siehe auch PEP 597).

Diese API wurde in Python 3.11 hinzugefügt.

Korrektur der Option encoding="locale"

PEP 597 fügte die Option encoding="locale" zu TextIOWrapper hinzu. Diese Option wird verwendet, um die Locale-Codierung explizit anzugeben. TextIOWrapper sollte die Locale-Codierung verwenden, wenn die Option angegeben ist, unabhängig von der Standard-Textcodierung.

Aber TextIOWrapper verwendet derzeit "UTF-8" im UTF-8-Modus, selbst wenn encoding="locale" angegeben ist. Dieses Verhalten widerspricht der Motivation von PEP 597. Das liegt daran, dass wir nicht erwartet haben, den UTF-8-Modus zum Standard zu machen, als Python seine Standard-Textcodierung änderte.

Diese Inkonsistenz sollte behoben werden, bevor der UTF-8-Modus zum Standard gemacht wird. TextIOWrapper sollte die Locale-Codierung verwenden, wenn encoding="locale" übergeben wird, auch im UTF-8-Modus.

Dieses Problem wurde in Python 3.11 behoben.

Abwärtskompatibilität

Die meisten Unix-Systeme verwenden UTF-8-Locales und Python aktiviert den UTF-8-Modus, wenn seine Locale C oder POSIX ist. Diese Änderung betrifft also hauptsächlich Windows-Benutzer.

Wenn ein Python-Programm von der Standardcodierung abhängt, kann diese Änderung zu UnicodeError, Mojibake oder sogar stiller Datenkorruption führen. Daher sollte diese Änderung laut angekündigt werden.

Dies ist die Richtlinie zur Behebung dieses Problems der Abwärtskompatibilität

  1. Deaktivieren Sie den UTF-8-Modus.
  2. Verwenden Sie EncodingWarning (PEP 597), um alle Stellen zu finden, die vom UTF-8-Modus betroffen sind.
    • Wenn die Option encoding weggelassen wird, erwägen Sie die Verwendung von encoding="utf-8" oder encoding="locale".
    • Wenn locale.getpreferredencoding() verwendet wird, erwägen Sie die Verwendung von "utf-8" oder locale.getencoding().
  3. Testen Sie die Anwendung mit UTF-8-Modus.

Vorherige Beispiele

  • Ruby hat in Ruby 3.0 (2020) die Standard-external_encoding unter Windows auf UTF-8 umgestellt.
  • Java hat in JDK 18 (2022) die Standard-Textcodierung auf UTF-8 umgestellt.

Sowohl Ruby als auch Java haben eine Option für Abwärtskompatibilität. Sie geben keine Warnung wie die EncodingWarning aus PEP 597 in Python für die Verwendung der Standardcodierung aus.

Abgelehnte Alternative

Implizite Codierung deprecaten

Das Deprecaten der Verwendung der Standardcodierung wird in Erwägung gezogen.

Es gibt jedoch viele Fälle, in denen die Standardcodierung nur für das Lesen/Schreiben von reinem ASCII-Text verwendet wird. Darüber hinaus sind solche Warnungen für plattformübergreifende Anwendungen, die unter Unix laufen, nicht nützlich.

Daher ist es zu mühsam, Benutzer zu zwingen, überall die encoding anzugeben. Das Ausgeben vieler DeprecationWarning führt dazu, dass Benutzer Warnungen ignorieren.

PEP 387 verlangt das Hinzufügen einer Warnung für abwärtsinkompatible Änderungen. Es verlangt jedoch nicht die Verwendung von DeprecationWarning. Die Verwendung einer optionalen EncodingWarning verletzt also nicht PEP 387.

Auch Java hat diese Idee in JEP 400 abgelehnt.

Verwendung von PYTHONIOENCODING für PIPES

Zur Erleichterung des Problems der Abwärtskompatibilität wird die Verwendung von PYTHONIOENCODING als Standardcodierung für PIPES im Modul subprocess in Betracht gezogen.

Mit dieser Idee können Benutzer Legacy-Codierungen für subprocess.Popen(text=True) auch im UTF-8-Modus verwenden.

Diese Idee macht jedoch die „Standardcodierung“ kompliziert. Und diese Idee ist ebenfalls abwärtsinkompatibel.

Daher wird diese Idee abgelehnt. Benutzer können den UTF-8-Modus deaktivieren, bis sie text=True durch encoding="utf-8" oder encoding="locale" ersetzen.

Wie man dies lehrt

Für neue Benutzer reduziert diese Änderung die Dinge, die gelehrt werden müssen. Benutzer müssen sich nicht im ersten Jahr mit Textcodierungen auseinandersetzen. Sie sollten sie lernen, wenn sie Nicht-UTF-8-Textdateien verwenden müssen.

Für bestehende Benutzer siehe den Abschnitt Abwärtskompatibilität.


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

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