El camí per comprovar 4 milions de línies de codi Python. Part 3

Presentem a la vostra atenció la tercera part de la traducció de material sobre el camí que va prendre Dropbox en implementar un sistema de verificació de tipus per al codi Python.

El camí per comprovar 4 milions de línies de codi Python. Part 3

→ Parts anteriors: primer и segon

Arriba a 4 milions de línies de codi escrit

Un altre repte important (i la segona preocupació més comuna entre els enquestats internament) va ser augmentar la quantitat de codi cobert per les comprovacions de tipus a Dropbox. Hem provat diversos enfocaments per resoldre aquest problema, des de fer créixer naturalment la mida de la base de codi escrit fins a centrar els esforços de l'equip mypy en la inferència de tipus automatitzada estàtica i dinàmica. Al final, semblava que no hi havia una estratègia guanyadora senzilla, però vam poder aconseguir un creixement ràpid del volum de codi anotat combinant molts enfocaments.

Com a resultat, el nostre repositori Python més gran (amb codi de fons) té prop de 4 milions de línies de codi anotat. El treball sobre l'escriptura de codi estàtic es va completar en aproximadament tres anys. Mypy ara admet diversos tipus d'informes de cobertura de codi que faciliten el seguiment del progrés de l'escriptura. En particular, podem generar informes sobre codi amb ambigüitats en els tipus, com, per exemple, l'ús explícit d'un tipus Any en anotacions que no es poden verificar o amb coses com la importació de biblioteques de tercers que no tenen anotacions de tipus. Com a part d'un projecte per millorar la precisió de la verificació de tipus a Dropbox, hem contribuït a millorar les definicions de tipus (els anomenats fitxers stub) d'algunes biblioteques de codi obert populars en un dipòsit centralitzat de Python. mecanografiat.

Hem implementat (i estandarditzat en PEPs posteriors) noves característiques del sistema de tipus que permeten tipus més precisos per a alguns patrons de Python específics. Un exemple notable d'això és TypeDict, que proporciona tipus per a diccionaris semblants a JSON que tenen un conjunt fix de claus de cadena, cadascun amb un valor del seu propi tipus. Continuarem ampliant el sistema de tipus. El nostre següent pas probablement serà millorar el suport per a les capacitats numèriques de Python.

El camí per comprovar 4 milions de línies de codi Python. Part 3
Nombre de línies de codi anotat: servidor

El camí per comprovar 4 milions de línies de codi Python. Part 3
Nombre de línies de codi anotat: client

El camí per comprovar 4 milions de línies de codi Python. Part 3
Nombre total de línies de codi anotat

Aquí teniu una visió general de les característiques principals de les coses que vam fer per augmentar la quantitat de codi anotat a Dropbox:

Rigor de l'anotació. A poc a poc hem augmentat els requisits per al rigor d'anotar el codi nou. Vam començar amb consells de linter que suggerien afegir anotacions als fitxers que ja tenien algunes anotacions. Ara necessitem anotacions de tipus als fitxers Python nous i a la majoria dels fitxers existents.

Mecanografia d'informes. Enviem als equips informes setmanals sobre el nivell d'escriptura del seu codi i donem consells sobre què s'ha d'anotar primer.

Popularització de mypy. Parlem de mypy als esdeveniments i parlem amb els equips per ajudar-los a començar amb les anotacions de tipus.

Enquestes. Realitzem enquestes periòdiques als usuaris per identificar problemes importants. Estem preparats per anar bastant lluny per resoldre aquests problemes (fins i tot creant un nou llenguatge per accelerar mypy!).

Rendiment. Hem millorat molt el rendiment de mypy utilitzant el dimoni i mypyc. Això es va fer per suavitzar els inconvenients que sorgeixen durant el procés d'anotació i per poder treballar amb grans quantitats de codi.

Integració amb editors. Hem creat eines per donar suport a l'execució de mypy als editors que són populars a Dropbox. Això inclou PyCharm, Vim i VS Code. Això va simplificar molt el procés d'anotar el codi i comprovar-ne la funcionalitat. Aquest tipus d'accions són habituals quan s'anota el codi existent.

Anàlisi estàtica. Hem creat una eina per inferir signatures de funcions mitjançant eines d'anàlisi estàtica. Aquesta eina només pot funcionar en situacions relativament senzilles, però ens va ajudar a augmentar la nostra cobertura de tipus de codi sense gaire esforç.

Suport per a biblioteques de tercers. Molts dels nostres projectes utilitzen el conjunt d'eines SQLAlchemy. Aprofita les capacitats dinàmiques de Python que els tipus PEP 484 no poden modelar directament. Nosaltres, d'acord amb PEP 561, vam crear el fitxer stub corresponent i vam escriure un connector per a mypy (codi obert), que millora el suport de SQLAlchemy.

Dificultats que hem trobat

El camí cap als 4 milions de línies de codi escrit no sempre ha estat fàcil per a nosaltres. En aquest camí ens vam trobar amb molts sots i vam cometre diversos errors. Aquests són alguns dels problemes que hem trobat. Esperem que parlar-ne ajudi a altres a evitar problemes similars.

Falten fitxers. Vam començar la nostra feina comprovant només una petita quantitat de fitxers. Tot el que no s'inclou en aquests fitxers no s'ha comprovat. Els fitxers es van afegir a la llista d'escaneig quan hi van aparèixer les primeres anotacions. Si s'ha importat alguna cosa des d'un mòdul situat fora de l'àmbit de verificació, estàvem parlant de treballar amb valors com ara Any, que no es van provar gens. Això va provocar una pèrdua important de precisió d'escriptura, especialment en les primeres etapes de la migració. Aquest enfocament ha funcionat sorprenentment bé fins ara, tot i que una situació típica és que afegir fitxers a l'abast de la revisió revela problemes en altres parts de la base de codi. En el pitjor dels casos, quan es van fusionar dues àrees aïllades de codi, en les quals, independentment l'una de l'altra, els tipus ja estaven verificats, va resultar que els tipus d'aquestes àrees eren incompatibles entre si. Això va comportar la necessitat de fer molts canvis a les anotacions. Mirant enrere ara, ens adonem que hauríem d'haver afegit mòduls bàsics de la biblioteca a l'àrea de verificació de tipus de mypy abans. Això faria que el nostre treball fos molt més previsible.

Anotar codi antic. Quan vam començar, teníem uns 4 milions de línies de codi Python existent. Estava clar que anotar tot aquest codi no era una tasca fàcil. Hem creat una eina anomenada PyAnnotate que pot recopilar informació de tipus a mesura que s'executen les proves i pot afegir anotacions de tipus al vostre codi en funció de la informació recollida. Tanmateix, no hem notat una adopció especialment generalitzada d'aquesta eina. La recopilació d'informació de tipus era lenta i les anotacions generades automàticament sovint requerien moltes edicions manuals. Vam pensar a executar aquesta eina automàticament cada vegada que revisem el codi o a recopilar informació de tipus basant-nos en l'anàlisi d'un petit volum de sol·licituds de xarxa reals, però vam decidir no fer-ho perquè qualsevol dels dos enfocaments era massa arriscat.

Com a resultat, es pot observar que la major part del codi va ser anotat manualment pels seus propietaris. Per guiar aquest procés en la direcció correcta, preparem informes sobre mòduls i funcions especialment importants que cal anotar. Per exemple, és important proporcionar anotacions de tipus per a un mòdul de biblioteca que s'utilitza en centenars de llocs. Però un servei antic que s'està substituint per un de nou ja no és tan important d'anotar. També estem experimentant amb l'ús de l'anàlisi estàtica per generar anotacions de tipus per al codi heretat.

Importacions cícliques. Més amunt, vaig parlar de les importacions cícliques (els "embolics de dependència"), l'existència de les quals dificultava l'acceleració de mypy. També hem hagut de treballar dur perquè mypy admeti tot tipus d'idiomes que són causats per aquestes importacions cícliques. Recentment hem completat un projecte important de redisseny del sistema que va solucionar la majoria dels problemes de mypy relacionats amb les importacions circulars. En realitat, aquests problemes van sorgir dels primers dies del projecte, de tornada d'Alore, el llenguatge educatiu en el qual es va centrar originalment el projecte mypy. La sintaxi d'Alor facilita la resolució de problemes amb les ordres d'importació cícliques. El mypy modern ha heretat algunes limitacions de la seva implementació anterior i senzilla (que s'adaptava molt bé a Alore). Python fa difícil treballar amb importacions circulars, principalment perquè les expressions són ambigües. Per exemple, una operació d'assignació pot definir realment un àlies de tipus. Mypy no sempre és capaç de detectar coses com aquesta fins que la major part del bucle d'importació s'hagi processat. No hi havia aquestes ambigüitats a Alore. Les decisions deficients preses en les primeres etapes del desenvolupament del sistema poden suposar una sorpresa desagradable per al programador molts anys després.

Resultats: el camí cap als 5 milions de línies de codi i nous horitzons

El projecte mypy ha recorregut un llarg camí: des dels primers prototips fins a un sistema que controla 4 milions de línies de tipus de codi de producció. A mesura que mypy va evolucionar, els suggeriments de tipus de Python es van estandarditzar. En aquests dies, s'ha desenvolupat un ecosistema potent al voltant d'escriure codi Python. Té un lloc per al suport de la biblioteca, conté eines auxiliars per a IDE i editors, té diversos sistemes de control de tipus, cadascun dels quals té els seus pros i contres.

Tot i que la verificació de tipus ja és un fet a Dropbox, crec que encara estem en els primers dies d'escriure codi Python. Crec que les tecnologies de verificació de tipus seguiran evolucionant i millorant.

Si encara no heu utilitzat la verificació de lletres al vostre projecte Python a gran escala, sàpiga que ara és un bon moment per començar a passar a l'escriptura estàtica. He parlat amb aquells que han fet una transició semblant. Cap d'ells es va penedir. La comprovació de tipus fa que Python sigui un llenguatge molt més adequat per desenvolupar projectes grans que "Python normal".

Benvolguts lectors! Feu servir la verificació de tipus als vostres projectes Python?

El camí per comprovar 4 milions de línies de codi Python. Part 3
El camí per comprovar 4 milions de línies de codi Python. Part 3

Font: www.habr.com

Afegeix comentari