Cesta k overeniu typov 4 miliónov riadkov Python kódu. Časť 3

Predstavujeme vám tretiu časť prekladu materiálu o ceste, ktorú prešla spoločnosť Dropbox pri zavádzaní systému overovania typov Python kódu.

Cesta k overeniu typov 4 miliónov riadkov Python kódu. Časť 3

→ Predchádzajúce časti: prvý a druhá

Dosiahnutie 4 miliónov riadkov typizovaného kódu

Ďalšou dôležitou úlohou (toto bola druhá najpopulárnejšia otázka, ktorá znepokojovala tých, ktorí sa zúčastnili interných prieskumov) bolo zvýšiť objem kódu v Dropboxe pokrytého overením typov. Vyskúšali sme niekoľko prístupov na riešenie tejto úlohy — od prirodzeného rastu objemu typizovanej kódovej základne po zameranie úsilia členov tímu mypy na statickom a dynamickom automatizovanom odvodení typov. Nakoniec sa vytvoril dojem, že neexistuje jednoduchá víťazná stratégia, ale podarilo sa nám dosiahnuť rýchly rast objemu anotovaného kódu kombinovaním viacerých prístupov.

Výsledkom je, že v našom najväčšom Python repozitári (s backend kódom) dosiahlo množstvo riadkov anotovaného kódu takmer 4 milióny. Práca na statickej typizácii kódu bola vykonaná približne za tri roky. Mypy teraz podporuje rôzne druhy správ o pokrytí kódom typmi, ktoré uľahčujú sledovanie priebehu typizácie. Konkrétne môžeme vytvárať správy pre kód s neurčitosťami v typoch, s takými napríklad ako explicitné použitie typu Any v anotáciách, ktoré nemožno overiť, alebo s takými, ako je import externých knižníc, v ktorých nie sú anotácie typov. V rámci projektu zameraného na zvýšenie presnosti overovania typov v Dropboxe sme prispevali k zlepšeniu definícií typov (tzv. stub súborov) pre niektoré populárne open-source knižnice v centralizovanom Python repozitári typeshed.

Implementovali sme (a štandardizovali v nasledujúcich PEP) nové funkčnosti systému typov, ktoré umožňujú používať presnejšie typy pre niektoré špecifické Python vzory. Významným príkladom toho je TypeDict, ktorý poskytuje typy pre JSON podobené slovníky, ktoré majú fixnú sadu reťazcových kľúčov, z ktorých každý má hodnotu vlastného typu. Pokračujeme v rozširovaní systému typov. Pravdepodobne naším ďalším krokom bude zlepšenie podpory funkcií Pythonu pre prácu s číslami.

Cesta k overeniu typov 4 miliónov riadkov Python kódu. Časť 3
Počet riadkov anotovaného kódu: server

Cesta k overeniu typov 4 miliónov riadkov Python kódu. Časť 3
Počet riadkov anotovaného kódu: klient

Cesta k overeniu typov 4 miliónov riadkov Python kódu. Časť 3
Celkový počet riadkov anotovaného kódu

Tu je prehľad hlavných funkcií akcií, ktoré sme vykonali na zvýšenie objemu anotovaného kódu v Dropboxe:

Prísnosť anotovania. Postupne sme zvyšovali požiadavky na prísnosť anotovania nového kódu. Začali sme odporúčaniami lintra, ktoré navrhovali pridávať anotácie do súborov, v ktorých už existujú niektoré anotácie. Teraz požadujeme prítomnosť typových anotácií v nových Python súboroch a vo väčšine existujúcich súborov.

Správy o typovaní. Každý týždeň posielame tímom správy o úrovni typovania ich kódu a poskytujeme rady, čo by mali prioritne anotovať.

Popularizácia mypy. Informujeme o mypy na rôznych podujatiach a komunikujeme s tímami, aby sme im pomohli začať používať typové anotácie.

Prieskumy. PPeriodicky vykonávame prieskumy používateľov na identifikáciu hlavných problémov. Sme pripravení ísť dosť ďaleko v riešení týchto problémov (až po vytvorenie nového jazyka pre urýchlenie mypy!).

Výkon. Výrazne sme zlepšili výkon mypy vďaka používaniu démona a mypyc. To sa urobilo, aby sa zmiernili ťažkosti spojené s anotovaním a aby sme mohli pracovať s veľkými objemami kódu.

Integrácia s editormi. Vytvorili sme prostriedky na podporu spúšťania mypy v editore, ktoré sú populárne v Dropboxe. Tieto zahŕňajú PyCharm, Vim a VS Code. To významne zjednodušilo proces vykonávania prác na anotovaní kódu a kontrole jeho funkčnosti. Takéto akcie sú zvyčajne charakteristické pri anotovaní existujúceho kódu.

Statická analýza. Vytvorili sme nástroj na výstup funkčných podpisov pomocou prostriedkov statickej analýzy. Tento nástroj môže fungovať len v relatívne jednoduchých situáciách, ale pomohol nám bez väčších úsilia zvýšiť pokrytie kódu typmi.

Podpora externých knižníc. Vo viacerých našich projektoch používame súbor nástrojov SQLAlchemy. V ňom využívame dynamické možnosti Pythona, ktoré typy PEP 484 nedokážu priamo modelovať. V súlade s PEP 561 sme vytvorili zodpovedajúci stub súbor a napísali plugin pre mypy (open-source), ktorý zlepšuje podporu SQLAlchemy.

Problémy, s ktorými sme sa stretli

Cesta k 4 miliónom riadkov typizovaného kódu nám nepriniesla vždy ľahkosti. Na tejto ceste sme sa stretli s nemalými jamami a urobili sme niekoľko chýb. Tu sú niektoré z problémov, s ktorými sme sa stretli. Dúfame, že rozprávanie o nich pomôže iným predchádzať podobným problémom.

Zmeškané súbory. Začínali sme prácu len s kontrolou malého objemu súborov. Všetko, čo nepatrilo do tohto počtu súborov, nebolo kontrolované. Súbory boli pridané do kontrolného zoznamu vtedy, keď sa v nich objavili prvé anotácie. Ak sa niečo importovalo z modulu umiestneného mimo oblasti kontroly, hovorili sme o práci s hodnotami typu Any, ktoré sa vôbec nekontrolovali. To viedlo k značnej strate presnosti typizácie, najmä v počiatočných fázach migrácie. Tento prístup sa predsa len ukázal byť prekvapivo účinný, aj keď typickou situáciou bolo, že pridanie súborov do oblasti kontroly odhalilo problémy v iných častiach kódovej bázy. V najhoršom prípade, keď sa spojili dve izolované oblasti kódu, v ktorých boli typy už skontrolované nezávisle, sa zistilo, že typy týchto oblastí sú navzájom nekompatibilné. To viedlo k potrebnosti vniesť mnoho zmien do anotácií. Teraz, keď sa ohladne spätne, si uvedomujeme, že sme mali čo najskôr pridať do oblasti kontroly typov mypy základné knižnicové moduly. To by našu prácu urobilo oveľa predvídateľnejšou.

Annotácia starého kódu. Keď sme začali pracovať, mali sme približne 4 milióny riadkov existujúceho Python kódu. Bolo jasné, že anotovanie všetkého tohto kódu je úloha, ktorá nie je jednoduchá. Vytvorili sme nástroj nazvaný PyAnnotate, ktorý dokáže zbierať informácie o typoch počas vykonávania testov a vie pridať do kódu typové anotácie na základe zozbieraných informácií. Avšak, najmä široké zavedenie tohto nástroja sme nezaznamenali. Zber informácií o typoch bol pomalý, automaticky generované anotácie často vyžadovali množstvo ručných úprav. Uvažovali sme o automatickom spustení tohto nástroja pri každej kontrole kódu alebo o tom, že zbierame informácie o typoch na základe analýzy určitého malého objemu reálnych sieťových požiadaviek, ale rozhodli sme sa to neurobiť, pretože ktorýkoľvek z týchto prístupov bol príliš riskantný.

Na konci môžeme poznamenať, že väčšina kódu bola ručne anotovaná jeho vlastníkmi. My, aby sme nasmerovali tento proces správnym smerom, pripravujeme správy o obzvlášť dôležitých moduloch a funkciách, ktoré je potrebné anotovať. Napríklad je dôležité vybaviť anotáciami typov knižničný modul, ktorý sa používa na stovkách miest. Starý servis, ktorý nahrádzajú novým, už nie je také dôležité anotovať. Okrem toho experimentujeme s použitím statickej analýzy na generovanie anotácií typov pre starý kód.

Cyklické importy. Predchádzajúce som hovoril o cyklických importoch (o "klbkách závislostí"), ktorých existencia sťažovala zrýchlenie mypy. Museli sme tiež tvrdo pracovať na tom, aby sme mypy vybavili podporou všetkých druhov idiomov, ktorých vznik spôsobujú tieto cyklické importy. Nedávno sme dokončili veľký projekt redesignu systému, ktorý odstránil väčšinu problémov mypy týkajúcich sa cyklických importov. Tieto problémy v skutočnosti vznikli už v raných dňoch projektu, ešte počas Alore, učebného jazyka, na ktorý bol projekt mypy pôvodne orientovaný. Syntax Alore umožňuje ľahko riešiť problémy s cyklickými príkazmi importu. Moderný mypy zdedil niektoré obmedzenia zo svojej rané jednoduché implementácie (ktorá bola skvelá pre Alore). Python komplikuje prácu s cyklickými importami predovšetkým z dôvodu nejednoznačnosti výrazov. Napríklad, počas operácie priraďovania hodnoty môže v skutočnosti byť definovaný alias typu. Mypy nie vždy dokáže identifikovať takéto veci, kým nie je spracovaná väčšina cyklu importu. V Alore takých nejednoznačností neexistovalo. Zlé rozhodnutia prijaté na raných fázach vývoja systému môžu programátorovi priniesť nepríjemné prekvapenie po mnohých rokoch.

Zhrnutie: cesta k 5 miliónom riadkov kódu a novým horizontom

Projekt mypy prešiel dlhú cestu — od raných prototypov až po systém, ktorý kontroluje typy produkčného kódu s objemom 4 milióny riadkov. Počas vývoja mypy bola uskutočnená štandardizácia typových návrhov v Pythone. V súčasnosti okolo typizácie kódu Pythonu vznikol silný ekosystém. Objavili sa tu podpora knižníc, existujú pomocné nástroje pre IDE a editory, a sú tu aj niekoľko systémov kontroly typov, z ktorých každý má svoje výhody a nevýhody.

Napriek tomu, že kontrola typov je už na Dropboxe považovaná za niečo samozrejmé, som presvedčený, že stále žijeme na úsvite typizácie kódu Python. Myslím si, že technológie kontroly typov budú naďalej vyvíjané a zdokonaľované.

Ak ešte nepoužívate kontrolu typov vo svojich veľkorozmerných projektoch v Pythone, vedzte, že teraz je veľmi vhodný čas na prechod na statickú typizáciu. Hovoril som s niekoľkými, ktorí takýto prechod urobili. Nikto z nich toho neľutoval. Kontrola typov robí z Pythona jazyk, ktorý je oveľa lepší na vývoj veľkých projektov ako obyčajný Python.

Vážení čitatelia! Používate kontrolu typov vo svojich projektoch v Pythone?

Cesta k overeniu typov 4 miliónov riadkov Python kódu. Časť 3
Cesta k overeniu typov 4 miliónov riadkov Python kódu. Časť 3

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster