Python Type Checker

4 Tools, um Ihren Code sauber zu halten

25.04.2023 von Serdar Yegulalp
Diese Type Checker für Python unterstützen Sie dabei, Ihren Code fehlerfrei zu halten.
Diese Type Checker empfehlen sich, um Ihren Python-Code fehlerfrei zu halten.
Foto: Casimiro PT - shutterstock.com

Python hatte anfangs keine Type Decorations, was auf das übergeordnete Ziel einzahlte, die Programmiersprache schnell und simpel zu gestalten. Flexible Object Types passen sich den "Drehungen und Wendungen" der Programmierarbeit an und helfen den Entwicklern, ihren Code übersichtlich zu halten.

Im Laufe der letzten Jahre hat Python jedoch Support für Type Annotations erhalten und eine ganze Software-Kultur geprägt, die sich dem Type Checking während der Entwicklung mit Python verschrieben hat. Python selbst überprüft keine Types zur Runtime - zumindest noch nicht. Ein qualitativ guter Type Checker, der die IDE Ihrer Wahl ergänzt ermöglicht es, Type Annotations in Python zu nutzen - und dabei viele gängige Fehler zu beseitigen, bevor sie in die Produktion gelangen.

Dieser Artikel zeigt Ihnen vier der wichtigsten Type Checker für Python. Sie alle folgen in etwa dem gleichen Muster, scannen Python-Code mit Type Annotations und geben entsprechendes Feedback. Dennoch erweitert jeder dieser Type Checker das Grundkonzept um seine eigenen, nützlichen Ergänzungen.

4 Python Type Checker, die Sie kennen sollten

Mypy

Ursprünglich bei Dropbox entwickelt, um die eigene interne Codebasis zu optimieren, war Mypy im Jahr 2012 vermutlich das erste statische Type-Checking-System für Python. Mypy wird immer noch weiterentwickelt und ist im Wesentlichen - auch wenn seitdem viele andere hinzugekommen sind - der Prototyp dafür, wie Type-Checking-Bibliotheken von Drittanbietern in Python funktionieren.

Mypy kann standalone oder über die Kommandozeile ausgeführt werden - oder als Teil eines Editors oder der Linter-Integration einer IDE fungieren. Diverse Editoren und IDEs integrieren mit Mypy - die Python-Erweiterung von Visual Studio Code etwa kann direkt damit arbeiten. Wird Mypy ausgeführt, generiert es Reportings über die Konsistenz Ihres Codes - auf Grundlage der zur Verfügung gestellten Typ-Informationen.

Enthält Ihr Code keine Type Annotations laufen die meisten Mypy-Überprüfungen ins Leere. Wenn Sie also eine Codebasis schrittweise annotieren, wird kein Code überprüft, der nicht überprüft werden soll. Davon abgesehen können Sie Mypy auch einsetzen, um nicht annotierten Code manuell zu flaggen. Das lässt sich je nach Bedarf mit unterschiedlicher "Strictness" erledigen.

Wenn Sie mit einer Codebasis von Grund auf neu beginnen und präventiv auf eine aggressive Linting-Strategie setzen wollen, können Sie die Option --strict verwenden, um jeglichen nicht-typisierten Code auszuschließen. Arbeiten Sie hingegen mit einer Legacy-Codebasis, die nicht viele Type Definitions enthält, können Sie auch auf "entspanntere" Optionen ausweichen - etwa indem Sie mit --disallow-untyped-defs nur untypisierte Funktionsdefinitionen verhindern, aber anderen untypisierten Code zulassen. Darüber hinaus verhindern Inline-Kommentare wie # type: ignore, dass einzelne Zeilen geflaggt werden.

Mypy kann PEP 484 Stub Files verarbeiten, wenn Sie Type Hints für die öffentlichen Schnittstellen eines Moduls verwenden möchten. Mit stubgen bietet Mypy auch ein Tool, das Stub-Dateien automatisiert aus vorhandenem Code generiert. Für nicht typisierten Code verwenden diese Generic Types, die sich nach Bedarf auszeichnen lassen.

Das Tool mypyc kompiliert typdekoriertes Python in ein C-Modul. Das kann entsprechende Codebasen beschleunigen - man könnte es also als einen experimentellen Weg sehen, Python zu einer schnelleren Sprache mit Type Annotations zu machen. Weil mypyc jedoch keine Annotationen für machine-native Types zulässt, ist es Cython in Sachen Speed unterlegen. Andererseits bedeutet Cythons benutzerdefinierte Syntax, dass die meisten Linter nicht eingesetzt werden können.

Pytype

Das von Google entwickelte Pytype unterscheidet sich von Mypy in er erster Linie dadurch, dass es auf Inferenz statt auf Type Decorators setzt. Anders ausgedrückt: Pytype versucht, Types zu bestimmen, indem es den Codefluss analysiert, anstatt sich ausschließlich auf Typ-Annotationen zu verlassen.

Wenn Ihre Operation zur Laufzeit funktioniert und keiner Annotation zuwiderläuft, wird Pytype nicht mucken. Das bedeutet jedoch auch, dass einige Flag-würdige Probleme (etwa eine Variable mit einem Typ deklarieren und das anschließend im gleichen Kontext neu definieren), unbemerkt bleiben. Laut Dokumentation soll dieses Problem (und andere) in Zukunft behoben werden.

Wenn Sie Ihren Code mit Typ-Annotationen versehen wollen, ist die Pytype-Funktion reveal_type besonders nützlich: Fügen Sie die Anweisung reveal_type(expr) in Ihren Code ein, wertet Pytype expr aus und gibt eine Meldung aus, die seinen Typ beschreibt.

Dabei sollten Sie beachten, dass bestimmte Verhaltensweisen von Pytype gesteuert werden, indem der Code um Attribute ergänzt wird. Wollen Sie beispielsweise verhindern, dass Pytype über fehlende Attribute oder dynamisch gesetzte Module meckert, müssen Sie der Klasse oder dem Modul das Attribut _HAS_DYNAMIC_ATTRIBUTES = True hinzufügen.

Pyright / Pylance

Microsofts Python Type Checker hört auf den Namen Pyright und ist Teil der Pylance-Erweiterung für Visual Studio Code (VS Code). Wenn Sie Letztgenanntes bereits verwenden, ist die Pylance-Erweiterung der bequemste Weg, um mit Pyright zu arbeiten. Das Tool bietet eine gute allgemeine Type-Checking- und Code-Linting-Experience - mit vielen der Annehmlichkeiten früherer Analyse-Tools für Python.

Wie Pytype ist auch Pyright in der Lage, mit Codebasen umzugehen, die keine Typinformationen enthalten. In diesen Fällen wird Pyright sein Bestes tun, um die verwendeten Typen zu ermitteln. Sie können also auch im Fall von älteren Codebasen ohne Typendeklarationen gute Ergebnisse erzielen.

Pyright ist in der Praxis sehr flexibel und passt sich dem Design realer Python-Projekte an. Wie andere Type Checker lässt sich auch Pyright projektspezifisch konfigurieren - entweder auf Projektbasis mit Hilfe einer JSON-Konfigurationsdatei oder als Teil einer pyproject.toml-Datei. Einzelne Pfade können in der Konfigurationsdatei ausgeschlossen oder ignoriert werden.

In VS Code können Workspaces mit verschiedenartigen Wurzeln jeweils ihre eigene Pyright-Konfiguration aufweisen - für den Fall, dass verschiedene Projektteile unterschiedliche Linting-Konfigurationen benötigen. In gleicher Weise können Sie mehrere "Execution Environments" innerhalb eines Projekts definieren, jede mit ihren eigenen venv- oder Importpfaden. Das macht Pyright zum mit Abstand granularsten der hier vorgestellten Linter.

Pyre

Dieses Tool wurde von Facebook und Instagram entwickelt und ist eigentlich zwei Tools in einem: ein Type Checker (Pyre) und ein statisches Tool zur Codeanalyse (Pysa). Beides ist darauf konzipiert, Hand in Hand zusammenzuarbeiten. Allerdings verlangt es dem Benutzer einiges ab, um die Vorteile voll ausnutzen zu können.

Pyre verfolgt einen ähnlichen Ansatz wie Pytype und Mypy: Nicht typisierter Code wird nachsichtiger behandelt als typisierter Code, so dass Sie mit einer nicht-typisierten Python-Codebasis beginnen und Annotationen Funktion für Funktion und Modul für Modul hinzufügen können. Schalten Sie den "strict mode" in einem Modul hinzu, markiert Pyre alle fehlenden Annotationen. Pyre arbeitet auch mit Stub-Dateien im .pyi-Format.

Pyre enthält auch eine Funktion, um Codebasen in ein typisiertes Format zu migrieren. Die Kommandozeilenoption infer nimmt eine Datei oder ein Verzeichnis auf, stellt Vermutungen über die verwendeten Typen auf und wendet die Annotationen auf die Dateien an. Sie sollten allerdings vorher eine Sicherungskopie Ihres Codes erstellen.

Während die Funktionen von Pyre denen der anderen hier beschriebenen Tools ähneln, ist Pysa einzigartig: Es führt eine "Taint-Analyse" des Codes durch, um potenzielle Sicherheitsprobleme zu erkennen. Dabei stützt es sich auf Flow-Analyse-Bibliotheken und markiert vermeintlich vulnerablen Code. Alles, was von diesem Code "berührt" wird, wird ebenfalls als "tainted" gekennzeichnet - Sie können allerdings Komponenten angeben, die Daten bereinigen und diese aus dem Taint-Graphen entfernen.

Ein Nachteil: Pysas Taint-Analysen-Bibliothek für Drittanbieterkomponenten ist nicht sonderlich umfangreich - Sie müssen also unter Umständen Ihr eigenes Modell entwickeln. Viele Taint-Analysen beziehen sich jedoch auf weitverbreitete Software, wie etwa das Web-Framework Django, die ORM von SQL Alchemy und die Data-Science-Bibliothek Pandas - ganz zu schweigen von Analysen für gängige Dateisystemprobleme. (fm)

Dieser Beitrag basiert auf einem Artikel unserer US-Schwesterpublikation Infoworld.