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

Python Enhancement Proposals

PEP 606 – Python-Kompatibilitätsversion

Autor:
Victor Stinner <vstinner at python.org>
Status:
Abgelehnt
Typ:
Standards Track
Erstellt:
18-Okt-2019
Python-Version:
3.9

Inhaltsverzeichnis

Zusammenfassung

Hinzufügen von sys.set_python_compat_version(version) zur Aktivierung teilweiser Kompatibilität mit der angeforderten Python-Version. Hinzufügen von sys.get_python_compat_version().

Modifizierung einiger Funktionen in der Standardbibliothek zur Implementierung teilweiser Kompatibilität mit Python 3.8.

Hinzufügen von sys.set_python_min_compat_version(version) zur Ablehnung der Abwärtskompatibilität mit Python-Versionen älter als version.

Hinzufügen der Kommandozeilenoptionen -X compat_version=VERSION und -X min_compat_version=VERSION. Hinzufügen der Umgebungsvariablen PYTHONCOMPATVERSION und PYTHONCOMPATMINVERSION.

Begründung

Die Notwendigkeit, sich häufig weiterzuentwickeln

Um relevant und nützlich zu bleiben, muss sich Python häufig weiterentwickeln; einige Verbesserungen erfordern inkompatible Änderungen. Jede inkompatible Änderung kann eine unbekannte Anzahl von Python-Projekten beeinträchtigen. Entwickler können sich entscheiden, eine Funktion deshalb nicht zu implementieren.

Benutzer möchten die neueste Python-Version erhalten, um neue Funktionen und bessere Leistung zu nutzen. Einige inkompatible Änderungen können sie daran hindern, ihre Anwendungen auf der neuesten Python-Version zu verwenden.

Dieser PEP schlägt vor, eine teilweise Kompatibilität mit alten Python-Versionen als Kompromiss hinzuzufügen, um beide Anwendungsfälle zu berücksichtigen.

Das Hauptproblem bei der Migration von Python 2 auf Python 3 ist nicht, dass Python 3 abwärts inkompatibel ist, sondern wie inkompatible Änderungen eingeführt wurden.

Teilweise Kompatibilität zur Minimierung des Wartungsaufwands für Python

Obwohl es technisch möglich wäre, volle Kompatibilität mit alten Python-Versionen bereitzustellen, schlägt dieser PEP vor, die Anzahl der Funktionen, die die Abwärtskompatibilität unterstützen, zu minimieren, um den Wartungsaufwand des Python-Projekts (CPython) zu reduzieren.

Jede Änderung, die eine Backport-Kompatibilität für eine Funktion einführt, sollte ordnungsgemäß diskutiert werden, um die langfristigen Wartungskosten abzuschätzen.

Der Code für die Abwärtskompatibilität wird mit jeder Python-Version fallweise entfernt. Jede Kompatibilitätsfunktion kann für eine unterschiedliche Anzahl von Python-Releases unterstützt werden, abhängig von ihren Wartungskosten und dem geschätzten Risiko (Anzahl der beeinträchtigten Projekte), wenn sie entfernt wird.

Die Wartungskosten entstehen nicht nur durch den Code, der die Abwärtskompatibilität implementiert, sondern auch durch zusätzliche Tests.

Von der Abwärtskompatibilität ausgeschlossene Fälle

Der Leistungsoverhead jeglichen Kompatibilitätscodes muss gering sein, wenn sys.set_python_compat_version() nicht aufgerufen wird.

Die C-API liegt außerhalb des Geltungsbereichs dieses PEP: Das Makro Py_LIMITED_API und die stabile ABI lösen dieses Problem auf andere Weise, siehe PEP 384: Defining a Stable ABI.

Sicherheitsfixes, die absichtlich die Abwärtskompatibilität brechen, erhalten keine Kompatibilitätsschicht; Sicherheit ist wichtiger als Kompatibilität. Zum Beispiel wurde http.client.HTTPSConnection in Python 3.4.3 modifiziert, um standardmäßig alle notwendigen Zertifikats- und Hostnamenprüfungen durchzuführen. Dies war eine bewusste Änderung, motiviert durch PEP 476: Enabling certificate verification by default for stdlib http clients (bpo-22417).

Die Python-Sprache bietet keine Abwärtskompatibilität.

Änderungen, die nicht klar inkompatibel sind, werden von diesem PEP nicht abgedeckt. Zum Beispiel änderte Python 3.9 das Standardprotokoll im pickle-Modul auf Protokoll 4, das erstmals in Python 3.4 eingeführt wurde. Diese Änderung ist bis Python 3.4 abwärtskompatibel. Es besteht keine Notwendigkeit, standardmäßig Protokoll 3 zu verwenden, wenn Kompatibilität mit Python 3.8 angefordert wird.

Die neuen Warnungen DeprecationWarning und PendingDeprecatingWarning in Python 3.9 werden im Python 3.8 Kompatibilitätsmodus nicht deaktiviert. Wenn ein Projekt seine Testsuite mit -Werror (jede Warnung als Fehler behandeln) ausführt, müssen diese Warnungen behoben oder spezifische Deprecation-Warnungen fallweise ignoriert werden.

Aktualisierung eines Projekts auf eine neuere Python-Version

Ohne Abwärtskompatibilität müssen alle inkompatiblen Änderungen auf einmal behoben werden, was zu einem Blocker-Problem führen kann. Dies ist umso schlimmer, wenn ein Projekt auf eine neuere Python-Version aktualisiert wird, die mehrere Releases von der alten Python-Version trennen.

Das Aufschieben eines Upgrades verschlimmert die Situation nur: Jeder übersprungene Release fügt mehr inkompatible Änderungen hinzu. Die technische Schuld steigt im Laufe der Zeit stetig an.

Mit Abwärtskompatibilität wird es möglich, Python in einem Projekt inkrementell zu aktualisieren, ohne alle Probleme auf einmal beheben zu müssen.

Das „Alles oder Nichts“-Prinzip ist ein Showstopper für die Portierung großer Python-2-Codebasen auf Python 3. Die Liste der inkompatiblen Änderungen zwischen Python 2 und Python 3 ist lang und wird mit jeder Python 3.x-Release länger.

Bereinigung von Python und DeprecationWarning

Eines der Mottos von Zen of Python (PEP 20) lautet:

Es sollte nur einen – und vorzugsweise nur einen – offensichtlichen Weg geben, es zu tun.

Wenn Python sich weiterentwickelt, entstehen zwangsläufig neue Wege. DeprecationWarnings werden ausgegeben, um die Verwendung des neuen Wegs vorzuschlagen, aber viele Entwickler ignorieren diese Warnungen, die standardmäßig stummgeschaltet sind (außer im __main__-Modul: siehe PEP 565). Einige Entwickler ignorieren einfach alle Warnungen, wenn es zu viele gibt, und kümmern sich erst um Ausnahmen, wenn der veraltete Code entfernt wird.

Manchmal hat die Unterstützung beider Wege geringe Wartungskosten, aber Entwickler ziehen es vor, den alten Weg zu verwerfen, um ihren Code zu bereinigen. Diese Art von Änderungen ist abwärts inkompatibel.

Einige Entwickler können das Ende der Python-2-Unterstützung als Gelegenheit nutzen, noch mehr inkompatible Änderungen als üblich einzuführen.

Das Hinzufügen einer optionalen Abwärtskompatibilität verhindert das Brechen von Anwendungen und ermöglicht es Entwicklern, diese Bereinigungen weiterhin durchzuführen.

Verteilung des Wartungsaufwands

Die Abwärtskompatibilität bezieht die Autoren inkompatibler Änderungen stärker in den Upgrade-Pfad ein.

Beispiele für Abwärtskompatibilität

Aliase für collections ABC

Aliase für collections.abc zu ABC-Klassen wurden aus dem collections-Modul in Python 3.9 entfernt, nachdem sie seit Python 3.3 als veraltet markiert waren. Zum Beispiel existiert collections.Mapping nicht mehr.

In Python 3.6 wurden Aliase in collections/__init__.py durch from _collections_abc import * erstellt.

In Python 3.7 wurde ein __getattr__() zum collections-Modul hinzugefügt, um bei erstmaligem Zugriff auf ein Attribut eine DeprecationWarning auszugeben.

def __getattr__(name):
    # For backwards compatibility, continue to make the collections ABCs
    # through Python 3.6 available through the collections module.
    # Note: no new collections ABCs were added in Python 3.7
    if name in _collections_abc.__all__:
        obj = getattr(_collections_abc, name)
        import warnings
        warnings.warn("Using or importing the ABCs from 'collections' instead "
                      "of from 'collections.abc' is deprecated since Python 3.3, "
                      "and in 3.9 it will be removed.",
                      DeprecationWarning, stacklevel=2)
        globals()[name] = obj
        return obj
    raise AttributeError(f'module {__name__!r} has no attribute {name!r}')

Die Kompatibilität mit Python 3.8 kann in Python 3.9 wiederhergestellt werden, indem die Funktion __getattr__() wieder hinzugefügt wird, aber nur, wenn Abwärtskompatibilität angefordert wird.

def __getattr__(name):
    if (sys.get_python_compat_version() < (3, 9)
       and name in _collections_abc.__all__):
        ...
    raise AttributeError(f'module {__name__!r} has no attribute {name!r}')

Veralteter open() „U“-Modus

Der "U"-Modus von open() ist seit Python 3.4 veraltet und löst eine DeprecationWarning aus. bpo-37330 schlägt vor, diesen Modus zu entfernen: open(filename, "rU") würde eine Ausnahme auslösen.

Diese Änderung fällt in die Kategorie „Bereinigung“: Sie ist nicht erforderlich, um eine Funktion zu implementieren.

Ein Abwärtskompatibilitätsmodus wäre trivial zu implementieren und würde von den Benutzern begrüßt werden.

Spezifikation

sys-Funktionen

Hinzufügen von 3 Funktionen zum sys-Modul

  • sys.set_python_compat_version(version): Legt die Python-Kompatibilitätsversion fest. Wenn sie bereits zuvor aufgerufen wurde, wird das Minimum der angeforderten Versionen verwendet. Löst eine Ausnahme aus, wenn sys.set_python_min_compat_version(min_version) aufgerufen wurde und version < min_version. version muss größer oder gleich (3, 0) sein.
  • sys.set_python_min_compat_version(min_version): Legt die **Mindest**-Kompatibilitätsversion fest. Löst eine Ausnahme aus, wenn sys.set_python_compat_version(old_version) zuvor aufgerufen wurde und old_version < min_version. min_version muss größer oder gleich (3, 0) sein.
  • sys.get_python_compat_version(): Ruft die Python-Kompatibilitätsversion ab. Gibt ein tuple aus 3 Ganzzahlen zurück.

Eine version muss ein Tupel aus 2 oder 3 Ganzzahlen sein. Die Version (major, minor) ist äquivalent zu (major, minor, 0).

Standardmäßig gibt sys.get_python_compat_version() die aktuelle Python-Version zurück.

Zum Beispiel, um Kompatibilität mit Python 3.8.0 anzufordern

import collections

sys.set_python_compat_version((3, 8))

# collections.Mapping alias, removed from Python 3.9, is available
# again, even if collections has been imported before calling
# set_python_compat_version().
parent = collections.Mapping

Offensichtlich hat der Aufruf von sys.set_python_compat_version(version) keinen Einfluss auf Code, der vor dem Aufruf ausgeführt wird. Verwenden Sie die Kommandozeilenoption -X compat_version=VERSION oder die Umgebungsvariable PYTHONCOMPATVERSIONVERSION=VERSION, um die Kompatibilitätsversion beim Python-Start festzulegen.

Kommandozeile

Hinzufügen der Kommandozeilenoptionen -X compat_version=VERSION und -X min_compat_version=VERSION: Ruft entsprechend sys.set_python_compat_version() und sys.set_python_min_compat_version() auf. VERSION ist ein Versionsstring mit 2 oder 3 Zahlen (major.minor.micro oder major.minor). Zum Beispiel ruft -X compat_version=3.8 sys.set_python_compat_version((3, 8)) auf.

Hinzufügen der Umgebungsvariablen PYTHONCOMPATVERSIONVERSION=VERSION und PYTHONCOMPATMINVERSION=VERSION=VERSION: Ruft entsprechend sys.set_python_compat_version() und sys.set_python_min_compat_version() auf. VERSION ist ein Versionsstring mit demselben Format wie die Kommandozeilenoptionen.

Abwärtskompatibilität

Die Einführung der Funktion sys.set_python_compat_version() bedeutet, dass sich eine Anwendung je nach Kompatibilitätsversion unterschiedlich verhält. Darüber hinaus kann sich die Anwendung, da die Version mehrmals verringert werden kann, je nach Importreihenfolge unterschiedlich verhalten.

Python 3.9 mit sys.set_python_compat_version((3, 8)) ist nicht vollständig mit Python 3.8 kompatibel: Die Kompatibilität ist nur teilweise.

Sicherheitsimplikationen

sys.set_python_compat_version() darf keine Sicherheitsfixes deaktivieren.

Alternativen

Bereitstellung einer Problemumgehung für jede inkompatible Änderung

Eine Anwendung kann die meisten inkompatiblen Änderungen, die sie betreffen, umgehen.

Zum Beispiel können collections-Aliase zurück hinzugefügt werden mit

import collections.abc
collections.Mapping = collections.abc.Mapping
collections.Sequence = collections.abc.Sequence

Behandlung der Abwärtskompatibilität im Parser

Der Parser wird modifiziert, um mehrere Versionen der Python-Sprache (Grammatik) zu unterstützen.

Der aktuelle Python-Parser kann dafür nicht einfach modifiziert werden. AST und Grammatik sind auf eine einzige Python-Version hartcodiert.

In Python 3.8 hat compile() eine undokumentierte Option _feature_version, um async und await nicht als Schlüsselwörter zu betrachten.

Die letzte große sprachlich inkompatible Änderung war in Python 3.7, die async und await zu echten Schlüsselwörtern machte. Es scheint, als ob Twisted das einzige betroffene Projekt war, und Twisted hatte eine einzige betroffene Funktion (es verwendete einen Parameter namens async).

Die Behandlung der Abwärtskompatibilität im Parser erscheint recht komplex, nicht nur für die Modifizierung des Parsers, sondern auch für Entwickler, die überprüfen müssen, welche Version der Python-Sprache verwendet wird.

from __future__ import python38_syntax

Fügen Sie pythonXY_syntax zum __future__-Modul hinzu. Dies würde Abwärtskompatibilität mit der Syntax von Python X.Y aktivieren, aber nur für die aktuelle Datei.

Mit dieser Option ist keine Änderung von sys.implementation.cache_tag erforderlich, um einen anderen .pyc-Dateinamen zu verwenden, da der Parser für dieselbe Eingabe immer dieselbe Ausgabe erzeugt (außer für die Optimierungsstufe).

Zum Beispiel:

from __future__ import python35_syntax

async = 1
await = 2

Aktualisierung von cache_tag

Modifizieren Sie den Parser, um sys.get_python_compat_version() zu verwenden, um die Version der Python-Sprache auszuwählen.

sys.set_python_compat_version() aktualisiert sys.implementation.cache_tag, um die Kompatibilitätsversion ohne die Mikro-Version als Suffix einzufügen. Zum Beispiel verwendet Python 3.9 standardmäßig 'cpython-39', aber sys.set_python_compat_version((3, 7, 2)) setzt cache_tag auf 'cpython-39-37'. Änderungen an der Python-Sprache sind nun in Mikro-Releases erlaubt.

Ein Problem ist, dass import asyncio wahrscheinlich fehlschlägt, wenn zuvor sys.set_python_compat_version((3, 6)) aufgerufen wurde. Der Code des asyncio-Moduls erfordert, dass async und await echte Schlüsselwörter sind (Änderung in Python 3.7).

Ein weiteres Problem ist, dass normale Benutzer keine .pyc-Dateien in Systemverzeichnisse schreiben können und sie daher nicht bei Bedarf erstellen können. Das bedeutet, dass die .pyc-Optimierung im Abwärtskompatibilitätsmodus nicht verwendet werden kann.

Eine Lösung dafür ist, den Python-Installer und die Python-Paket-Installer so zu modifizieren, dass sie .pyc-Dateien nicht nur für die aktuelle Python-Version, sondern auch für mehrere ältere Python-Versionen (bis Python 3.0?) vorkompilieren.

Jede .py-Datei hätte 3n .pyc-Dateien (3 Optimierungsstufen), wobei n die Anzahl der unterstützten Python-Versionen ist. Das bedeutet zum Beispiel 6 statt 3 .pyc-Dateien, um Python 3.8 und Python 3.9 zu unterstützen.

Vorübergehendes Moratorium für inkompatible Änderungen

Im Jahr 2009 schlug PEP 3003 „Python Language Moratorium“ ein temporäres Moratorium (Aussetzung) aller Änderungen an der Python-Sprachsyntax, -Semantik und den Built-ins für Python 3.1 und Python 3.2 vor.

Im Mai 2018 wurde während der Diskussionen zu PEP 572 auch vorgeschlagen, die Python-Änderungen zu verlangsamen: siehe den Thread in python-dev Slow down…

Barry Warsaws Aufruf dazu:

Ich glaube nicht, dass der Weg für Python, in den nächsten 10 Jahren relevant und nützlich zu bleiben, darin besteht, die gesamte Sprachentwicklung einzustellen. Wer weiß, wie die Computerlandschaft in 5 Jahren aussehen wird, geschweige denn in 10? Etwas so Willkürliches wie ein 10-jähriges Moratorium ist (wieder meiner Meinung nach) ein Todesurteil für die Sprache.

PEP 387

PEP 387 – Backwards Compatibility Policy schlägt einen Prozess zur Durchführung inkompatibler Änderungen vor. Der Hauptpunkt ist der 4. Schritt des Prozesses

Prüfen Sie auf Feedback. Benutzer, die nicht an den ursprünglichen Diskussionen beteiligt waren, können jetzt kommentieren, nachdem sie die Warnung gesehen haben. Möglicherweise neu überdenken.

PEP 497

PEP 497 – A standard mechanism for backward compatibility schlägt verschiedene Lösungen zur Bereitstellung von Abwärtskompatibilität vor.

Mit Ausnahme der __past__-Mechanismus-Idee schlägt PEP 497 keine konkreten Lösungen vor.

Wenn eine inkompatible Änderung an der Kernsprachsyntax oder -semantik vorgenommen wird, ist es die Politik von Python-dev, nach Möglichkeit einen Mechanismus für Abwärtskompatibilität in Betracht zu ziehen und für zukünftige Python-Versionen bereitzustellen, nachdem die breaking change standardmäßig übernommen wurde, zusätzlich zu allen für Vorwärtskompatibilität vorgeschlagenen Mechanismen wie neuen future_statements.

Beispiele für inkompatible Änderungen

Python 3.8

Beispiele für inkompatible Änderungen in Python 3.8

  • (Während der Beta-Phase) PyCode_New() erforderte einen neuen Parameter: dies brach alle Cython-Erweiterungen (alle Projekte, die vorkompilierten Cython-Code verteilen). Diese Änderung wurde während der 3.8 Beta-Phase rückgängig gemacht und stattdessen eine neue Funktion PyCode_NewWithPosOnlyArgs() hinzugefügt.
  • types.CodeType erforderte einen zusätzlichen obligatorischen Parameter. Die Funktion CodeType.replace() wurde hinzugefügt, um Projekte dabei zu unterstützen, nicht mehr von der exakten Signatur des CodeType-Konstruktors abhängig zu sein.
  • C-Erweiterungen werden nicht mehr mit libpython verknüpft.
  • sys.abiflags wurde von 'm' auf einen leeren String geändert. Zum Beispiel ist das Programm python3.8m verschwunden.
  • Die C-Struktur PyInterpreterState wurde opak gemacht.
  • XML-Attributreihenfolge: bpo-34160. Betroffene Projekte

Abwärtskompatibilität kann für keine dieser Änderungen hinzugefügt werden. Zum Beispiel liegen Änderungen in der C-API und im Build-System außerhalb des Geltungsbereichs dieses PEP.

Siehe What’s New In Python 3.8: API and Feature Removals für alle Änderungen.

Siehe auch den Abschnitt Porting to Python 3.8 in What’s New In Python 3.8.

Python 3.7

Beispiele für inkompatible Änderungen in Python 3.7

  • async und await sind jetzt reservierte Schlüsselwörter.
  • Mehrere undokumentierte interne Importe wurden entfernt. Ein Beispiel ist, dass os.errno nicht mehr verfügbar ist; verwenden Sie stattdessen direkt import errno. Beachten Sie, dass solche undokumentierten internen Importe jederzeit ohne Vorankündigung entfernt werden können, selbst in Mikro-Version-Releases.
  • Unbekannte Escapes, die aus '\' und einem ASCII-Buchstaben bestehen, in Ersatzvorlagen für re.sub() wurden in Python 3.5 als veraltet markiert und führen nun zu einem Fehler.
  • Die Funktion asyncio.windows_utils.socketpair() wurde entfernt: Sie war ein Alias für socket.socketpair().
  • asyncio exportiert die Module selectors und _overlapped nicht mehr als asyncio.selectors und asyncio._overlapped. Ersetzen Sie from asyncio import selectors durch import selectors.
  • PEP 479 ist für allen Code in Python 3.7 aktiviert, was bedeutet, dass StopIteration-Ausnahmen, die direkt oder indirekt in Coroutinen und Generatoren ausgelöst werden, in RuntimeError-Ausnahmen umgewandelt werden.
  • socketserver.ThreadingMixIn.server_close() wartet nun, bis alle Nicht-Daemon-Threads abgeschlossen sind. Setzen Sie das neue Klassenattribut block_on_close auf False, um das Verhalten vor 3.7 zu erhalten.
  • Der Typ struct.Struct.format ist jetzt str anstelle von bytes.
  • Die repr für datetime.timedelta wurde geändert, um die Schlüsselwortargumente in der Ausgabe einzuschließen.
  • Die tracemalloc.Traceback-Frames werden jetzt von ältesten zu neuesten sortiert, um konsistenter mit traceback zu sein.

Die Hinzufügung von Abwärtskompatibilität für die meisten dieser Änderungen wäre einfach.

Siehe auch den Abschnitt Porting to Python 3.7 in What’s New In Python 3.7.

Mikro-Releases

Manchmal werden in Mikro-Releases (die micro-Version in major.minor.micro) inkompatible Änderungen eingeführt, um Fehler oder Sicherheitslücken zu beheben. Beispiele sind:

  • Python 3.7.2, Module compileall und py_compile: Der Standardwert für den Parameter invalidation_mode wurde auf None aktualisiert; die Umgebungsvariable SOURCE_DATE_EPOCH überschreibt nicht mehr den Wert des Arguments invalidation_mode, sondern bestimmt stattdessen dessen Standardwert.
  • Python 3.7.1, Module xml: Der SAX-Parser verarbeitet standardmäßig keine allgemeinen externen Entitäten mehr, um die Sicherheit standardmäßig zu erhöhen.
  • Python 3.5.2, os.urandom(): Unter Linux, wenn der getrandom()-Systemaufruf blockiert (der Entropiepool von urandom ist noch nicht initialisiert), wird auf das Lesen von /dev/urandom zurückgegriffen.
  • Python 3.5.1, sys.setrecursionlimit(): Eine Ausnahme RecursionError wird nun ausgelöst, wenn das neue Limit bei der aktuellen Rekursionstiefe zu niedrig ist.
  • Python 3.4.4, ssl.create_default_context(): RC4 wurde aus dem Standard-Cipher-String entfernt.
  • Python 3.4.3, http.client: HTTPSConnection führt standardmäßig alle notwendigen Zertifikats- und Hostnamenprüfungen durch.
  • Python 3.4.2, email.message: EmailMessage.is_attachment() ist nun eine Methode anstelle einer Eigenschaft, zur Konsistenz mit Message.is_multipart().
  • Python 3.4.1, os.makedirs(name, mode=0o777, exist_ok=False): Vor Python 3.4.1, wenn exist_ok True war und das Verzeichnis existierte, würde makedirs() immer noch einen Fehler auslösen, wenn mode nicht mit dem Modus des existierenden Verzeichnisses übereinstimmte. Da dieses Verhalten nicht sicher implementiert werden konnte, wurde es in Python 3.4.1 entfernt (bpo-21082).

Beispiele für Änderungen in Mikro-Releases, die nicht abwärts inkompatibel sind

  • Die Konstante ssl.OP_NO_TLSv1_3 wurde zu 2.7.15, 3.6.3 und 3.7.0 für die Abwärtskompatibilität mit OpenSSL 1.0.2 hinzugefügt.
  • typing.AsyncContextManager wurde zu Python 3.6.2 hinzugefügt.
  • Das Modul zipfile akzeptiert seit Python 3.6.2 ein Pfad-ähnliches Objekt.
  • loop.create_future() wurde in Python 3.5.2 im Modul asyncio hinzugefügt.

Für diese Arten von Änderungen ist kein Abwärtskompatibilitätscode erforderlich.

Referenzen

Angenommene PEPs

Entwurfs-PEPs


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

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