Programmiersprache: Python 3.9 tauscht den Parser aus

Das Release markiert einige grundsätzliche Änderungen für die Weiterentwicklung von Python, allen voran ein strafferer Releasezyklus und ein neuer Parser

In Pocket speichern vorlesen Druckansicht 20 Kommentare lesen
Python
Lesezeit: 4 Min.
Inhaltsverzeichnis

Zum geplanten Releasedatum ist Python 3.9 erschienen. Mit dem Release bekommt die Programmiersprache einen neuen Parser, der flexiblere Erweiterungen ermöglichen soll. Hinsichtlich der Syntax sind die Union-Operatoren für Dictionaries und das erweiterte Type Hinting für Collections erwähnenswert. Außerdem gibt es zwei neue Hilfsfunktionen für Strings.

Version 3.9, das sich seit Mai 2020 in der Betaphase befand, markiert zudem einen Fahrplanwechsel: Statt wie bisher alle 18 Monate stehen nun jährlich neue Releases an. Python 3.8 war im Oktober 2019 erschienen, und im November hatte Brett Cannon, Mitglied des Steering Council von Python, den neuen Releasezyklus angekündigt. Im nächsten Jahr steht als Nachfolger jedoch anders als beispielsweise bei TypeScript mit seiner Dezimalzählweise nicht Version 4.0 an, sondern für 2021 ist mit Python 3.10 ein inkrementelles Update in Planung.

CPython nutzt seit Anbeginn der Programmiersprache vor 30 Jahren einen LL(1)-Parser, was konkret bedeutet, dass er von links nach rechts und mit einer Linksableitung arbeitet (Left-to-right, Leftmost derivation) und dabei ein Token vorausschauen kann. Die Arbeitsweise ist zwar performant, bringt aber einige Einschränkungen mit sich.

Daher führt das PEP 617 (Python Enhancement Proposal) einen neuen Parser ein, der nach dem Prinzip der Parsing Expression Grammar (PEG) funktioniert. Im Sommer 2019 hat der Python-Schöpfer Guido van Rossum eine Blogserie zur Funktionsweise des PEG-Parsers und der Motivation für den Wechsel verfasst.

Zu den wesentlichen Kritikpunkten gehört, dass das Nachvorneschauen auf nur ein weiteres Token die Möglichkeiten der Syntax einschränkt. Außerdem verwendet Python bereits Konstrukte, die sich nicht mit der LL(1)-Grammatik vertragen und die der Parser nur mit Tricks verarbeiten kann. Ganz ungangenehm kann das Zusammenspiel mit linksrekursiver Syntax werden, die im ungünstigsten Fall zu Endlosschleifen beim Parsen und damit zu Stack-Overflow-Fehlern führt.

Der neue PEG-Parser soll in etwa dieselbe Performance wie der bisherige LL(1)-Parser aufweisen, ist aber deutlich flexibler. Im aktuellen Release hat er keine direkten Auswirkungen auf die Sprache, aber Python 3.10 entsteht mit Blick auf erhöhte Flexibilität. Im kommenden Release wird der LL(1)-Parser nicht mehr enthalten sein. Python 3.9 nutzt standardmäßig den neuen Parser, aber der alte lässt sich über den Kommandozeilenparameter -X oldparser oder die Umgebungsvariable PYTHONOLDPARSER=1 verwenden.

Hinsichtlich der Syntax ist der Merge-Operator | für dict zu nennen, der als PEP 584 Einzug in die Sprache hält. Er verbindet zwei Dictionaries. Das Ergebnis enthält dabei alle Elemente aus beiden Quellen, und bei doppelten Schlüsseln hält der letzte in der Kette Einzug:

d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'c': 4, 'd': 5}

d3 = d1 | d2
print(d3)

# f�hrt zu folgender Ausgabe, bei der der
# Eintrag c aus dem zweiten Dictionary stammt
{'a': 1, 'b': 2, 'c': 4, 'd': 5}

d3 = d2 | d1
print(d3)

# nimmt dagegen den Eintrag c aus 
# dem ersten Dictonary, aber den
{'d': 5, 'a': 1, 'b': 2, 'c': 3}

Zusätzlich zum regulären Merge-Operator ist auch der Einsatz über den Update-Operator |= möglich, bei dem das Ergebnis der Vereinigung im ersten Dictionary steht.

Das PEP 585 erweitert das Type Hinting für Collections. Genauer lassen sich explizite Typangaben für die integrierten generischen Typen wie list oder dict verwenden, beispielsweise in strList: list[str] oder intList = list[int](). Entwickler müssen damit für die Typhinweise nicht mehr die entsprechenden Varianten wie List oder Dict aus dem typing-Modul importieren.

Ebenfalls nennenswert sind die mit dem PEP 616 eingeführten Methoden, um Strings am Anfang oder Ende zu beschneiden. Die Methoden entfernen keine feste Anzahl an Zeichen, sondern vorne beziehungsweise hinten stehende Zeichenketten, wenn diese vorhanden sind. Als Beispiel führt der PEP das CPython-Modul cookijar.py auf, das derzeit zum Entfernen der umschließenden Anführungszeichen folgenden Code nutzt:

def strip_quotes(text):
    if text.startswith('"'):
        text = text[1:]
    if text.endswith('"'):
        text = text[:-1]
    return text

Mit den neuen Hilfsfunktionen genügt ein Einzeiler ohne if-Klauseln für das Bereinigen:

def strip_quotes(text):
    return text.removeprefix('"').removesuffix('"')

Nennenswert ist zudem, dass laut PEP 614 Dekoratoren künftig aus beliebigen Ausdrücken bestehen dürfen und nicht mehr zwingend einen führenden Namen mit einem Punkt aufweisen müssen. Weitere Neuerungen in Python 3.9 lassen sich dem Python-Insider-Blog und der "What's New"-Seite in der Dokumentation entnehmen.

Das Release ist auf der offiziellen Downloadseite verfügbar. Wer einen Blick auf die nahe Zukunft der Programmiersprache werfen möchte, findet dort auch die erste Alpha-Version von Python 3.10. Gleichzeitig endet der Support für Python 3.5 endgültig.

(rme)