VĂ€gen till typkontroll av 4 miljoner rader Python-kod. Del 3

Vi presenterar tredje delen av översÀttningen av materialet om den resa som Dropbox har genomgÄtt för att införa ett system för typkontroll av Python-kod.

VĂ€gen till typkontroll av 4 miljoner rader Python-kod. Del 3

→ Tidigare delar: första och tvĂ„

Att nÄ 4 miljoner rader typad kod

En annan viktig uppgift (detta var det nÀst mest populÀra problemet som oroade dem som deltog i interna enkÀter) var att öka mÀngden kod i Dropbox som tÀcks av typkontroller. Vi testade flera tillvÀgagÄngssÀtt för att lösa denna uppgift - frÄn naturlig tillvÀxt av den typade kodbasen till att fokusera insatserna för mypy-teamet pÄ statisk och dynamisk automatisk typutvinning. Slutligen skapades intrycket att det inte finns nÄgon enkel vinnande strategi, men vi lyckades uppnÄ en snabb ökning av mÀngden annoterad kod genom att kombinera flera angreppssÀtt.

Som ett resultat hade vÄr största Python-repo (med backend-kod) nÀstan 4 miljoner rader annoterad kod. Arbetet med statisk typning av koden genomfördes under cirka tre Är. Mypy stöder nu olika typer av rapporter om typnings tÀckning, som förenklar övervakningen av typningsprocessen. Specifikt kan vi generera rapporter för kod med typosÀkerheter, som till exempel ersÀttande typer Any i annotationerna som inte kan verifieras, eller sÄdana som importerar externa bibliotek som saknar typanoteringar. Som en del av projektet för att förbÀttra noggrannheten i typkontrollen i Dropbox har vi bidragit till förbÀttringen av typdefinitionerna (de sÄ kallade stub-filerna) för nÄgra populÀra open-source-bibliotek i det centraliserade Python-repoet typeshed.

Vi har implementerat (och standardiserat i efterföljande PEP) nya funktioner i typ systemet som möjliggör mer exakta typer för vissa specifika Python-mönster. Ett viktigt exempel pÄ detta Àr TypeDict, som tillhandahÄller typer för JSON-liknande ordböcker som har en fast uppsÀttning strÀngnycklar, var och en med ett vÀrde av sin egen typ. Vi kommer att fortsÀtta att utöka typ systemet. Troligtvis blir vÄrt nÀsta steg att förbÀttra stödet för Python-funktioner som arbetar med siffror.

VĂ€gen till typkontroll av 4 miljoner rader Python-kod. Del 3
Antal rader av annoterad kod: server

VĂ€gen till typkontroll av 4 miljoner rader Python-kod. Del 3
Antal rader av annoterad kod: kund

VĂ€gen till typkontroll av 4 miljoner rader Python-kod. Del 3
Totalt antal rader av annoterad kod

HÀr Àr en översikt över de huvudsakliga funktionerna i de ÄtgÀrder vi har vidtagit för att öka mÀngden annoterad kod i Dropbox:

Strikthet i annoteringen. Vi har gradvis ökat kraven pÄ strikthet för annotering av ny kod. Vi började med linternas rekommendationer, dÀr vi föreslog att lÀgga till annotationer i filer som redan hade vissa annoteringar. Nu krÀver vi att typannotationer finns i nya Python-filer och i de flesta befintliga filer.

Typningsrapporter. Vi skickar veckovisa rapporter till teamen om typningsgraden av deras kod och ger förslag pÄ vad som bör annoteras först.

FrÀmjande av mypy. Vi pratar om mypy pÄ olika evenemang och kommunicerar med teamen för att hjÀlpa dem komma igÄng med typannotationer.

Undersökningar. Vi genomför periodiska anvÀndarundersökningar för att identifiera de största problemen. Vi Àr beredda att gÄ ganska lÄngt för att lösa dessa problem (inklusive att skapa ett nytt sprÄk för att pÄskynda mypy!).

Prestanda. Vi har avsevÀrt förbÀttrat prestandan av mypy genom att anvÀnda en daemon och mypyc. Detta gjordes för att jÀmna ut obehagligheter som uppstÄr vid annoteringen och för att kunna hantera stora kodmÀngder.

Integration med redaktörer. Vi har skapat verktyg för att stödja körning av mypy i de redaktörer som Àr populÀra i Dropbox. Detta inkluderar PyCharm, Vim och VS Code. Detta har gjort processen för att utföra arbetet med annotering av kod och verifiering av dess funktionalitet betydligt enklare. Liknande ÄtgÀrder Àr vanligt förekommande vid annotering av befintlig kod.

Statisk analys. Vi har skapat ett verktyg för att generera funktionssignaturer med hjÀlp av statiska analysverktyg. Detta verktyg kan endast fungera i jÀmförelsevis enkla situationer, men det har hjÀlpt oss att utan större anstrÀngning öka typbeteckningen av koden.

Stöd för externa bibliotek. MÄnga av vÄra projekt anvÀnder verktyget SQLAlchemy. Det anvÀnder Python-dynamiska funktioner som typerna i PEP 484 inte kan modellera direkt. Enligt PEP 561 har vi skapat den nödvÀndiga stub-filen och skrivit ett plugin för mypy.öppen kÀllkod), vilket förbÀttrar stöd för SQLAlchemy.

SvÄrigheter vi stötte pÄ

VÀgen till 4 miljoner rader typad kod har inte alltid varit lÀtt. PÄ denna vÀg har vi stött pÄ mÄnga hinder och gjort nÄgra misstag. HÀr Àr nÄgra av de problem vi stött pÄ. Vi hoppas att vÄr berÀttelse kan hjÀlpa andra att undvika liknande problem.

Saknade filer. Vi började arbetet med att kontrollera enbart ett litet antal filer. Allt som inte ingick i dessa filer kontrollerades inte. Filer lades till i kontrollistan nÀr de fick sina första annotationer. Om nÄgot importerades frÄn en modul utanför kontrollomrÄdet, handlade det om att arbeta med vÀrden av typen Any, som överhuvudtaget inte kontrollerades. Detta ledde till en betydande förlust av typernas noggrannhet, sÀrskilt i de tidiga migrationsstegen. Denna metod fungerade förvÄnansvÀrt bra, Àven om det ofta var sÄ att tillÀgg av filer till kontrollomrÄdet visade problem pÄ andra delar av kodbasen. I det vÀrsta fallet, nÀr tvÄ isolerade kodomrÄden förenades, dÀr typerna oberoende var granskade, visade det sig att typerna i dessa omrÄden var oförenliga med varandra. Detta ledde till att mÄnga Àndringar behövde göras i annotationerna. Nu, nÀr vi ser tillbaka, förstÄr vi att vi borde ha lagt till grundbiblioteksmodulerna i typerna för mypy sÄ tidigt som möjligt. Det skulle ha gjort vÄrt arbete mycket mer förutsÀgbart.

Annotering av gammal kod. NÀr vi började arbeta hade vi omkring 4 miljoner rader redan existerande Python-kod. Det stod klart att annotering av all denna kod var en tuff uppgift. Vi skapade ett verktyg kallat PyAnnotate som kan samla in typinformation under körning av tester och lÀgga till typannoteringar i koden baserat pÄ den insamlade informationen. Men vi mÀrkte ingen sÀrskilt utbredd anvÀndning av detta verktyg. Insamlingen av typinformation var lÄngsam, och automatiskt genererade annoteringar krÀvde ofta mÄnga manuella justeringar. Vi övervÀgde att automatiskt köra detta verktyg vid varje kodgranskning eller att samla in typinformation baserat pÄ analys av ett litet antal verkliga nÀtverksförfrÄgningar, men beslutade att inte göra det, eftersom nÄgon av dessa metoder skulle vara för riskabel.

I slutÀndan kan man konstatera att största delen av koden annoterades manuellt av dess Àgare. Vi för att styra denna process i rÀtt riktning, förbereder rapporter om sÀrskilt viktiga moduler och funktioner som behöver annoteras. Till exempel Àr det viktigt att förse biblioteksmodulen, som anvÀnds pÄ hundratals stÀllen, med typannoteringar. Men den gamla tjÀnsten som ersÀtts av den nya Àr inte lika viktig att annotera. Dessutom experimenterar vi med att anvÀnda statisk analys för att generera typannoteringar för den gamla koden.

Cykliska importer. Tidigare talade jag om cykliska importer (om "beroendetrassel"), vars existens har försvÄrat hastighetsoptimeringen av mypy. Vi har ocksÄ fÄtt arbeta hÄrt för att ge mypy stöd för alla typer av idiom som orsakas av dessa cykliska importer. Nyligen avslutade vi ett stort projekt för att redesigna systemet, vilket ÄtgÀrdade de flesta problem med mypy relaterade till cykliska importer. Dessa problem hÀrstammade faktiskt frÄn de mycket tidiga dagarna av projektet, Ànda frÄn Alore, det undervisningssprÄk som ursprungligen projektet mypy var inriktat pÄ. Syntaxen i Alore gör det enkelt att hantera problem med cykliska importkommandon. Det moderna mypy har Àrvt vissa begrÀnsningar frÄn sin tidiga, okomplicerade implementation (som passade bra för Alore). Python komplicerar arbetet med cykliska importer frÀmst pÄ grund av uttryckens tvetydighet. Till exempel kan en typalias faktiskt definieras under en assignmentsoperation. Mypy Àr inte alltid kapabel att upptÀcka sÄdana saker förrÀn en stor del av importcykeln har behandlats. I Alore fanns det inga sÄdana tvetydigheter. DÄliga beslut som fattades i de tidiga utvecklingsstadierna av systemet kan överraska programmeraren flera Är senare.

Sammanfattning: vÀgen till 5 miljoner rader kod och nya horisonter

Projektet mypy har kommit lĂ„ngt — frĂ„n tidiga prototyper till ett system som kontrollerar typerna av produktionskod bestĂ„ende av 4 miljoner rader. Under mypy:s utveckling har standardisering av typ-hints genomförts i Python. Idag har en stark ekosystem kring typning av Python-kod utvecklats. Det finns stöd för bibliotek, verktyg för IDE och redigerare, och flera typen kontrollerande system, var och en med sina egna fördelar och nackdelar.

Även om typkontroller redan uppfattas som en sjĂ€lvklarhet pĂ„ Dropbox, Ă€r jag övertygad om att vi fortfarande lever i gryningen av typning av Python-kod. Jag tror att teknologier för typkontroll kommer att fortsĂ€tta att utvecklas och förbĂ€ttras.

Om du inte har anvÀnt typkontroller i ditt storskaliga Python-projekt, vet att det nu Àr en utmÀrkt tid att börja övergÄ till statisk typning. Jag har pratat med dem som gjort en sÄdan övergÄng. Ingen av dem har Ängrat det. Typkontroll gör Python till ett sprÄk som Àr betydligt mer lÀmpat för att utveckla stora projekt Àn "vanlig Python".

KÀra lÀsare! AnvÀnder du typkontroller i dina Python-projekt?

VĂ€gen till typkontroll av 4 miljoner rader Python-kod. Del 3
VĂ€gen till typkontroll av 4 miljoner rader Python-kod. Del 3

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster