Die Möglichkeit, 4 Millionen Zeilen Python-Code zu überprüfen. Teil 3

Wir stellen Ihnen den dritten Teil der Übersetzung des Materials auf dem Weg vor, den Dropbox eingeschlagen hat, und führen ein System zur Überprüfung der Arten von Python-Code ein.



→ Vorherige Teile: erster und zweiter

Erreichen von 4 Millionen Zeilen eingegebenen Codes


Eine weitere wichtige Aufgabe (dies war das zweitbeliebteste Problem, das diejenigen beunruhigte, die an internen Umfragen teilnahmen) war die Erhöhung der Codemenge in Dropbox, die mit Typprüfungen abgedeckt war. Wir haben verschiedene Ansätze zur Lösung dieses Problems ausprobiert - vom natürlichen Wachstum des Volumens der typisierten Codebasis bis zum Fokus der Bemühungen des mypy-Teams auf statische und dynamische automatisierte Typinferenz. Infolgedessen schien es keine einfache Gewinnstrategie zu geben, aber wir konnten durch die Kombination vieler Ansätze ein schnelles Wachstum des Volumens an kommentiertem Code erzielen.

In unserem größten Python-Repository (mit Backend-Code) hat die Anzahl der mit Anmerkungen versehenen Codezeilen fast 4 Millionen erreicht. Die Arbeiten zur statischen Typisierung des Codes wurden in etwa drei Jahren durchgeführt. Mypy unterstützt jetzt verschiedene Arten von Code-Coverage-Berichten, die die Überwachung des Tippfortschritts erleichtern. Insbesondere können wir Berichte über den Code mit Unsicherheiten in Typen generieren, z. B. die explizite Verwendung des Any Typs in nicht überprüfbaren Annotationen oder den Import von Bibliotheken von Drittanbietern, die keine Typanmerkungen enthalten. Im Rahmen eines Projekts zur Erhöhung der Genauigkeit der Typprüfung in Dropbox haben wir dazu beigetragen, die Typdefinitionen (sogenannte Stub-Dateien) für einige beliebte Open Source-Bibliotheken im typisierten zentralisierten Python-Repository zu verbessern.

Wir haben neue Funktionen des Typsystems implementiert (und in nachfolgenden PEPs standardisiert), die es uns ermöglichen, präzisere Typen für einige bestimmte Python-Muster zu verwenden. Ein bemerkenswertes Beispiel hierfür ist TypeDict , das Typen für JSON-ähnliche Wörterbücher mit einem festen Satz von Zeichenfolgenschlüsseln TypeDict , von denen jedes einen eigenen Wert hat. Wir werden das Typensystem weiter ausbauen. Wahrscheinlich wird unser nächster Schritt darin bestehen, die Unterstützung für Pythons Fähigkeit, mit Zahlen zu arbeiten, zu verbessern.


Anzahl der Zeilen mit kommentiertem Code: Server


Anzahl der Zeilen mit kommentiertem Code: Client


Die Gesamtzahl der Zeilen mit kommentiertem Code

Hier ist eine Übersicht über die Hauptfunktionen der Aktionen, die wir durchgeführt haben, um das Volumen des mit Anmerkungen versehenen Codes in Dropbox zu erhöhen:

Die Strenge der Annotation. Wir haben die Anforderungen an die Genauigkeit der Annotation des neuen Codes schrittweise erhöht. Wir haben mit Linter-Tipps begonnen, die das Hinzufügen von Anmerkungen zu Dateien vorschlagen, die bereits einige Anmerkungen enthalten. Jetzt benötigen wir Typanmerkungen in den neuen Python-Dateien und in den meisten vorhandenen Dateien.

Berichte eingeben. Wir senden wöchentliche Berichte an Teams über den Grad der Eingabe ihres Codes und geben Tipps, was überhaupt kommentiert werden sollte.

Mypy populär machen. Wir sprechen bei verschiedenen Veranstaltungen über Mypy und kommunizieren mit Teams, um ihnen zu helfen, Typanmerkungen zu verwenden.

Umfragen. Wir führen regelmäßig Benutzerumfragen durch, um wichtige Probleme zu identifizieren. Wir sind bereit, weit genug zu gehen, um diese Probleme zu lösen (bis hin zur Schaffung einer neuen Sprache, um Mypy zu beschleunigen!).

Leistung. Wir haben die Leistung von mypy durch die Verwendung von Daemon und mypyc erheblich verbessert. Dies wurde durchgeführt, um die Unannehmlichkeiten auszugleichen, die während des Anmerkungsprozesses auftreten, und um mit großen Mengen an Code arbeiten zu können.

Integration mit Redakteuren. Wir haben Tools entwickelt, um den Start von mypy in Editoren zu unterstützen, die bei Dropbox beliebt sind. Dies umfasst PyCharm-, Vim- und VS-Code. Dies vereinfachte das Annotieren des Codes und das Überprüfen seiner Leistung erheblich. Solche Aktionen sind normalerweise typisch, wenn vorhandener Code mit Anmerkungen versehen wird.

Statische Analyse Wir haben ein Tool zum Ausgeben von Funktionssignaturen mithilfe statischer Analysewerkzeuge erstellt. Dieses Tool kann nur in relativ einfachen Situationen verwendet werden, hat uns jedoch dabei geholfen, die Abdeckung von Typen mit geringem Aufwand zu erhöhen.

Unterstützung für Bibliotheken von Drittanbietern. Viele unserer Projekte verwenden das SQLAlchemy-Toolkit. Es nutzt die dynamischen Funktionen von Python, die die PEP 484-Typen nicht direkt modellieren können. Laut PEP 561 haben wir die entsprechende Stub-Datei erstellt und ein Plugin für mypy ( Open Source ) geschrieben, das die SQLAlchemy-Unterstützung verbessert.

Die Schwierigkeiten, denen wir begegnet sind


Der Weg zu 4 Millionen Zeilen getippten Codes war für uns nicht immer einfach. Auf diesem Weg haben wir viele Löcher getroffen und einige Fehler gemacht. Hier sind einige der Probleme, auf die wir gestoßen sind. Wir hoffen, dass die Geschichte über sie anderen hilft, solche Probleme zu vermeiden.

Übersprungene Dateien. Wir haben zunächst nur eine kleine Anzahl von Dateien überprüft. Alles, was nicht in der Anzahl dieser Dateien enthalten ist, wurde nicht überprüft. Dateien wurden der Checkliste hinzugefügt, als die ersten Anmerkungen darin erschienen. Wenn etwas aus einem Modul importiert wurde, das sich außerhalb des Prüfbereichs befindet, haben wir über die Arbeit mit Werten vom Typ Any , die überhaupt nicht geprüft wurden. Dies führte zu einem erheblichen Verlust der Tippgenauigkeit, insbesondere in den frühen Stadien der Migration. Dieser Ansatz hat bisher überraschend gut funktioniert, obwohl es typisch war, dass das Hinzufügen von Dateien zum Scanbereich Probleme in anderen Teilen der Codebasis aufzeigt. Im schlimmsten Fall stellte sich heraus, dass die Typen dieser Bereiche nicht miteinander kompatibel waren, wenn zwei isolierte Codebereiche kombiniert wurden, in denen die Typen unabhängig voneinander bereits überprüft wurden. Dies machte es notwendig, viele Änderungen an den Anmerkungen vorzunehmen. Rückblickend verstehen wir, dass wir dem Bereich zur Überprüfung des mypy-Typs so früh wie möglich grundlegende Bibliotheksmodule hinzufügen sollten. Dies würde unsere Arbeit viel vorhersehbarer machen.

Alten Code kommentieren. Als wir anfingen, hatten wir ungefähr 4 Millionen Zeilen vorhandenen Python-Codes. Es war klar, dass das Kommentieren des gesamten Codes keine leichte Aufgabe war. Wir haben ein Tool namens PyAnnotate erstellt, das während der Testausführung Typinformationen erfassen und dem Code basierend auf den gesammelten Informationen Typanmerkungen hinzufügen kann. Eine besonders weit verbreitete Einführung dieses Tools haben wir jedoch nicht bemerkt. Das Eingeben von Informationen zu Typen war langsam. Automatisch generierte Anmerkungen erforderten häufig viele manuelle Änderungen. Wir haben darüber nachgedacht, dieses Tool jedes Mal automatisch zu starten, wenn Sie den Code überprüfen, oder Typinformationen basierend auf einer Analyse einiger kleiner realer Netzwerkanforderungen zu sammeln, haben uns jedoch dagegen entschieden, da einer dieser Ansätze zu riskant ist.

Infolgedessen kann festgestellt werden, dass der größte Teil des Codes von seinen Eigentümern manuell mit Anmerkungen versehen wurde. Um diesen Prozess in die richtige Richtung zu lenken, erstellen wir Berichte zu besonders wichtigen Modulen und Funktionen, die mit Anmerkungen versehen werden müssen. Beispielsweise ist es wichtig, Typanmerkungen mit dem Bibliotheksmodul bereitzustellen, das an Hunderten von Stellen verwendet wird. Das Kommentieren des alten Dienstes, der durch einen neuen ersetzt wird, ist jedoch nicht mehr so ​​wichtig. Wir experimentieren auch mit statischer Analyse, um Typanmerkungen für alten Code zu generieren.

Schleifenimporte. Früher habe ich über zyklische Importe („Gewirr von Abhängigkeiten“) gesprochen, deren Existenz die Beschleunigung von Mypy erschwerte. Darüber hinaus mussten wir hart arbeiten, um mypy bei der Unterstützung aller Arten von Redewendungen zu unterstützen, die durch diese zyklischen Importe verursacht wurden. Wir haben kürzlich ein umfangreiches Projekt zur Neugestaltung des Systems abgeschlossen, mit dem die meisten zyklischen Importprobleme von mypy behoben wurden. Diese Probleme entstanden in der Tat aus den frühen Tagen des Projekts, zurück von Alore, der Bildungssprache, an der sich mypy ursprünglich orientierte. Die Alore-Syntax erleichtert die Lösung der Probleme zyklischer Importbefehle. Modern mypy hat einige Einschränkungen von seiner frühen genialen Implementierung geerbt (die für Alore großartig funktioniert hat). Python macht es schwierig, mit zirkulären Importen zu arbeiten, hauptsächlich aufgrund der Mehrdeutigkeit von Ausdrücken. Beispielsweise kann während einer Zuweisungsoperation tatsächlich ein Typalias bestimmt werden. Mypy ist nicht immer in der Lage, solche Dinge zu erkennen, bis der größte Teil des Importzyklus verarbeitet wurde. Alore hatte solche Unklarheiten nicht. In den frühen Stadien der Systementwicklung getroffene erfolglose Entscheidungen können einen Programmierer nach vielen Jahren unangenehm überraschen.

Zusammenfassung: Der Weg zu 5 Millionen Codezeilen und neuen Horizonten


Das mypy-Projekt hat einen langen Weg zurückgelegt - von frühen Prototypen bis zu einem System, das die Arten von Produktionscode mit einem Volumen von 4 Millionen Zeilen steuert. Im Verlauf von mypy wurden Typhinweise in Python standardisiert. In diesen Tagen hat sich ein leistungsfähiges Ökosystem für die Eingabe von Python-Code entwickelt. Es hat einen Platz zur Unterstützung von Bibliotheken gefunden, es enthält Hilfstools für IDEs und Editoren, es verfügt über mehrere Typsteuerungssysteme, von denen jedes seine Vor- und Nachteile hat.

Trotz der Tatsache, dass die Typprüfung in Dropbox bereits als selbstverständlich angesehen wird, bin ich mir sicher, dass wir noch am Anfang der Eingabe von Python-Code leben. Ich denke, dass sich die Technologien zur Typprüfung weiterentwickeln und verbessern werden.

Wenn Sie in Ihrem großen Python-Projekt keine Typprüfungen verwendet haben, sollten Sie wissen, dass jetzt ein guter Zeitpunkt ist, um mit dem Übergang zur statischen Typisierung zu beginnen. Ich habe mit denen gesprochen, die einen ähnlichen Übergang gemacht haben. Keiner von ihnen bereute es. Die Typsteuerung verwandelt Python in eine Sprache, die für die Entwicklung großer Projekte viel besser ist als "normales Python".

Liebe Leser! Verwenden Sie die Typsteuerung in Ihren Python-Projekten?


Source: https://habr.com/ru/post/de468237/


All Articles