Veröffentlichung der Programmiersprache Python 3.11

Nach einem Jahr der Entwicklung wurde eine bedeutende Version der Programmiersprache Python 3.11 veröffentlicht. Dieser neue Zweig wird für anderthalb Jahre unterstützt, danach werden für weitere dreieinhalb Jahre Korrekturen zur Behebung von Sicherheitsanfälligkeiten bereitgestellt.

Gleichzeitig hat das Alpha-Testing des Zweigs Python 3.12 begonnen (gemäß dem neuen Entwicklungszeitplan beginnt die Arbeit an einem neuen Zweig fünf Monate vor der Veröffentlichung des vorherigen Zweigs und erreicht zur nächsten Veröffentlichung den Alpha-Teststatus). Der Zweig Python 3.12 wird sieben Monate lang im Alpha-Release sein, während dieser Zeit werden neue Funktionen hinzugefügt und Fehler behoben. Danach werden drei Monate lang Beta-Tests durchgeführt, in denen die Hinzufügung neuer Funktionen untersagt ist und alle Anstrengungen auf die Fehlerbehebung konzentriert werden. Die letzten zwei Monate vor der Veröffentlichung wird sich der Zweig im Release-Kandidaten-Status befinden, in dem eine endgültige Stabilisierung durchgeführt wird.

Zu den Neuerungen in Python 3.11 gehören:

  • Es wurden erhebliche Arbeiten zur Leistungsoptimierung durchgeführt. Der neue Zweig umfasst Änderungen zur Beschleunigung und Inline-Bereitstellung von Funktionsaufrufen, zur Anwendung schneller Interpreter für typischen Operationen (x+x, x*x, x-x, a[i], a[i] = z, f(arg) C(arg), o.method(), o.attr = z, *seq), sowie Optimierungen, die von den Projekten Cinder und HotPy vorbereitet wurden. Je nach Art der Last wird eine Geschwindigkeitssteigerung des Codes von 10-60% festgestellt. Im Durchschnitt hat sich die Leistung beim Durchlaufen des Testsets pyperformance um 25% erhöht.

    Der Mechanismus zur Bytecode-Caching wurde überarbeitet, was die Startzeit des Interpreters um 10-15% verkürzt hat. Objekte mit Code und Bytecode werden jetzt statisch vom Interpreter platziert, was es ermöglicht, die Phasen der Demarshalisierung des aus dem Cache extrahierten Bytecodes und der Umwandlung von Objekten mit Code für die Platzierung im dynamischen Speicher zu beseitigen.

  • Bei der Anzeige von Rückverfolgungen in Diagnosenachrichten wird jetzt die Information über den Ausdruck ausgegeben, der den Fehler verursacht hat (zuvor wurde nur die Zeile hervorgehoben, ohne dass detailliert wurde, welcher Teil der Zeile den Fehler verursacht hat). Erweiterte Informationen zur Rückverfolgung sind auch über die API abrufbar und können verwendet werden, um einzelne Bytecode-Anweisungen mit einer bestimmten Position im Quellcode zu verknüpfen, indem die Methode codeobject.co_positions() oder die C-API-Funktion PyCode_Addr2Location() verwendet wird. Diese Änderung erleichtert die Fehlersuche bei Problemen, die mit verschachtelten Wörterbuchobjekten, mehrfachen Funktionsaufrufen und komplexen arithmetischen Ausdrücken verbunden sind. Traceback (most recent call last): File «calculation.py», line 54, in result = (x / y / z) * (a / b / c) ~~~~~~^~~ ZeroDivisionError: division by zero
  • Die Unterstützung für Ausnahmegruppen wurde hinzugefügt, was dem Programm ermöglicht, mehrere verschiedene Ausnahmen gleichzeitig zu generieren und zu verarbeiten. Für die Gruppierung mehrerer Ausnahmen und ihren gemeinsamen Aufruf wurden die neuen Ausnahmetypen ExceptionGroup und BaseExceptionGroup eingeführt, und um einzelne Ausnahmen aus einer Gruppe zu extrahieren, wurde der Ausdruck „except*“ hinzugefügt.
  • In der Klasse BaseException wurde die Methode add_note() hinzugefügt, die es ermöglicht, einen Textvermerk an eine Ausnahme anzuhängen, z. B. um kontextbezogene Informationen hinzuzufügen, die zum Zeitpunkt der Auslösung der Ausnahme nicht verfügbar sind.
  • Ein spezieller Typ Self wurde hinzugefügt, der die aktuelle geschlossene Klasse darstellt. Self kann verwendet werden, um Methoden zu annotieren, die eine Instanz ihrer Klasse zurückgeben, auf einfachere Weise als bei Verwendung von TypeVar. class MyLock: def __enter__(self) -> Self: self.lock() return self
  • Ein spezieller Typ LiteralString wurde hinzugefügt, der nur string-Literale enthalten kann, die mit dem Typ LiteralString kompatibel sind (d.h. rohe Strings und Strings des Typs LiteralString, jedoch keine willkürlichen und keine kombinierten Strings mit dem Typ str). Der Typ LiteralString kann verwendet werden, um die Übergabe von string-Argumenten an Funktionen einzuschränken, bei denen willkürliche Teile von Strings zu Sicherheitsanfälligkeiten führen können, beispielsweise bei der Erstellung von Strings für SQL-Abfragen oder Shell-Befehle. def run_query(sql: LiteralString) -> … … def caller( arbitrary_string: str, query_string: LiteralString, table_name: LiteralString, ) -> None: run_query(«SELECT * FROM students») # ok run_query(literal_string) # ok run_query(«SELECT * FROM » + literal_string) # ok run_query(arbitrary_string) # Fehler run_query( # Fehler f»SELECT * FROM students WHERE name = {arbitrary_string}» )
  • Der Typ TypeVarTuple wurde hinzugefügt, der die Verwendung von variablen Generika ermöglicht, im Gegensatz zu TypeVar, das nicht nur einen Typ, sondern eine beliebige Anzahl von Typen abdeckt.
  • Das Standardbibliothek-Modul tomllib mit Funktionen zum Parsen des TOML-Formats wurde hinzugefügt.
  • Es wurde die Möglichkeit eingeführt, einzelne Elemente typisierter Wörterbücher (TypedDict) mit den Bezeichnungen Required und NotRequired zu kennzeichnen, um erforderliche und nicht erforderliche Felder zu definieren (standardmäßig sind alle deklarierten Felder verpflichtend, es sei denn, der Parameter total ist auf False gesetzt). class Movie(TypedDict): title: str year: NotRequired[int] m1: Movie = {«title»: «Black Panther», «year»: 2018} # OK m2: Movie = {«title»: «Star Wars»} # OK (Feld year ist optional) m3: Movie = {«year»: 2022} # Fehler, das erforderliche Feld title wurde nicht ausgefüllt)
  • Der asyncio-Modul wurde um die Klasse TaskGroup erweitert, die einen asynchronen Kontextmanager implementiert, der auf den Abschluss einer Gruppe von Aufgaben wartet. Das Hinzufügen von Aufgaben zur Gruppe erfolgt über die Methode create_task(). async def main(): async with asyncio.TaskGroup() as tg: task1 = tg.create_task(some_coro(…)) task2 = tg.create_task(another_coro(…)) print(«Beide Aufgaben sind jetzt abgeschlossen.»)
  • Ein Dekorator für Klassen, Methoden und Funktionen @dataclass_transform wurde hinzugefügt, bei deren Angabe das System zur statischen Typprüfung das Objekt so behandelt, als würde der Dekorator @dataclasses.dataclass verwendet. Im folgenden Beispiel wird die Klasse CustomerModel bei der Typprüfung analog zur Klasse mit dem Dekorator @dataclasses.dataclass behandelt, d.h. als hätte sie eine __init__-Methode, die die Variablen id und name erlaubt. @dataclass_transform() class ModelBase: … class CustomerModel(ModelBase): id: int name: str
  • In regulären Ausdrücken wurde die Möglichkeit zur Verwendung der atomaren Gruppierung ((?>…)) und der gierigen (possessive) Quantifizierer (*+, ++, ?+, {m,n}+) hinzugefügt.
  • Die Befehlszeilenoption „-P“ und die Umgebungsvariable PYTHONSAFEPATH wurden hinzugefügt, um das automatische Anhängen potenziell unsicherer Datei-Paths an sys.path zu deaktivieren.
  • Das Dienstprogramm py.exe für die Windows-Plattform wurde erheblich verbessert, mit Unterstützung für die Syntax „-V:<company>/<tag>“ zusätzlich zu „-<major>.<minor>“.
  • Viele Makros in der C-API wurden in normale oder statische Inline-Funktionen umgewandelt.
  • Die folgenden Module wurden als veraltet erklärt und werden in der Veröffentlichung von Python 3.13 entfernt: uu, cgi, pipes, crypt, aifc, chunk, msilib, telnetlib, audioop, nis, sndhdr, imghdr, nntplib, spwd, xdrlib, cgitb, mailcap, ossaudiodev und sunau. Die Funktionen PyUnicode_Encode* wurden entfernt.

Quelle: opennet.ru

60GB SSD 8Gb DDR4