Cesta k typovej kontrole 4 miliónov riadkov kódu Python. Časť 3

Predstavujeme vám tretiu časť prekladu materiálu o ceste, ktorou sa Dropbox vydal pri implementácii systému kontroly typu pre kód Python.

Cesta k typovej kontrole 4 miliónov riadkov kódu Python. Časť 3

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

Dosiahnutie 4 miliónov riadkov napísaného kódu

Ďalšou veľkou výzvou (a druhou najčastejšou obavou medzi interne opýtanými) bolo zvýšenie množstva kódu pokrytého typovými kontrolami v Dropboxe. Na vyriešenie tohto problému sme vyskúšali niekoľko prístupov, od prirodzeného zväčšovania veľkosti typovanej kódovej základne až po zameranie úsilia tímu mypy na statické a dynamické automatizované odvodzovanie typov. Nakoniec sa zdalo, že neexistuje žiadna jednoduchá víťazná stratégia, ale dokázali sme dosiahnuť rýchly rast objemu anotovaného kódu kombináciou mnohých prístupov.

Výsledkom je, že naše najväčšie úložisko Pythonu (s koncovým kódom) má takmer 4 milióny riadkov anotovaného kódu. Práce na písaní statického kódu boli ukončené približne za tri roky. Mypy teraz podporuje rôzne typy správ o pokrytí kódu, ktoré uľahčujú sledovanie priebehu písania. Najmä môžeme generovať správy o kóde s nejednoznačnosťami v typoch, ako je napríklad explicitné použitie typu Any v anotáciách, ktoré sa nedajú overiť, alebo s vecami, ako je import knižníc tretích strán, ktoré nemajú anotácie typu. V rámci projektu na zlepšenie presnosti kontroly typov v Dropboxe sme prispeli k zlepšeniu definícií typov (tzv. stub files) pre niektoré populárne open source knižnice v centralizovanom úložisku Python. typizovaný.

Implementovali sme (a štandardizovali sme v nasledujúcich PEP) nové funkcie typového systému, ktoré umožňujú presnejšie typy pre niektoré špecifické vzory Pythonu. Pozoruhodným príkladom toho je TypeDict, ktorá poskytuje typy pre slovníky podobné JSON, ktoré majú pevnú sadu kľúčov reťazcov, z ktorých každý má hodnotu svojho vlastného typu. Typový systém budeme naďalej rozširovať. Naším ďalším krokom bude pravdepodobne zlepšenie podpory numerických schopností Pythonu.

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

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

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

Tu je prehľad hlavných funkcií vecí, ktoré sme urobili, aby sme zvýšili množstvo anotovaného kódu v Dropboxe:

Prísnosť anotácie. Postupne sme zvyšovali požiadavky na prísnosť anotovania nového kódu. Začali sme s linterovými tipmi, ktoré navrhovali pridať anotácie do súborov, ktoré už nejaké anotácie mali. Teraz vyžadujeme anotácie typu v nových súboroch Python a vo väčšine existujúcich súborov.

Zadávanie správ. Tímom posielame týždenné správy o úrovni zadávania ich kódu a dávame rady, čo by malo byť anotované ako prvé.

Popularizácia mypy. Hovoríme o mypy na podujatiach a hovoríme s tímom, aby sme im pomohli začať s anotáciami typu.

Ankety. Vykonávame pravidelné používateľské prieskumy, aby sme identifikovali hlavné problémy. Sme pripravení zájsť pri riešení týchto problémov dosť ďaleko (dokonca aj vytvorením nového jazyka na zrýchlenie mypy!).

Výkon. Výrazne sme zlepšili výkon mypy pomocou démona a mypyc. Bolo to urobené s cieľom odstrániť nepríjemnosti, ktoré vznikajú počas procesu anotácie, a aby bolo možné pracovať s veľkým množstvom kódu.

Integrácia s editormi. Vytvorili sme nástroje na podporu spúšťania mypy v editoroch, ktoré sú populárne na Dropboxe. To zahŕňa PyCharm, Vim a VS Code. To značne zjednodušilo proces anotovania kódu a kontroly jeho funkčnosti. Tieto typy akcií sú bežné pri anotácii existujúceho kódu.

Statická analýza. Vytvorili sme nástroj na odvodenie podpisov funkcií pomocou nástrojov statickej analýzy. Tento nástroj môže fungovať iba v relatívne jednoduchých situáciách, ale pomohol nám zvýšiť pokrytie typov kódu bez veľkého úsilia.

Podpora pre knižnice tretích strán. Mnohé z našich projektov využívajú súpravu nástrojov SQLAlchemy. Využíva dynamické schopnosti Pythonu, 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), čo zlepšuje podporu SQLAlchemy.

Ťažkosti, s ktorými sme sa stretli

Cesta k 4 miliónom riadkov napísaného kódu pre nás nebola vždy jednoduchá. Na tejto ceste sme narazili na veľa výmoľov a urobili sme niekoľko chýb. Toto sú niektoré z problémov, s ktorými sme sa stretli. Dúfame, že rozprávanie o nich pomôže ostatným vyhnúť sa podobným problémom.

Chýbajúce súbory. Našu prácu sme začali kontrolou len malého množstva súborov. Čokoľvek, čo nie je zahrnuté v týchto súboroch, nebolo skontrolované. Súbory boli pridané do skenovacieho zoznamu, keď sa v nich objavili prvé anotácie. Ak bolo niečo importované z modulu umiestneného mimo rozsahu overovania, potom sme hovorili o práci s hodnotami ako Any, ktoré neboli vôbec testované. To viedlo k výraznej strate presnosti písania, najmä v počiatočných štádiách migrácie. Tento prístup doteraz fungoval prekvapivo dobre, hoci typická situácia je, že pridanie súborov do rozsahu kontroly odhalí problémy v iných častiach kódovej základne. V najhoršom prípade, keď sa zlúčili dve izolované oblasti kódu, v ktorých sa nezávisle od seba už kontrolovali typy, sa ukázalo, že typy týchto oblastí sú navzájom nekompatibilné. To viedlo k potrebe vykonať veľa zmien v anotáciách. Keď sa teraz pozrieme späť, uvedomíme si, že moduly základnej knižnice sme mali pridať do oblasti kontroly typu mypy skôr. Vďaka tomu by bola naša práca oveľa predvídateľnejšia.

Anotovanie starého kódu. Keď sme začínali, mali sme asi 4 milióny riadkov existujúceho kódu Pythonu. Bolo jasné, že anotovať celý tento kód nie je ľahká úloha. Vytvorili sme nástroj s názvom PyAnnotate, ktorý dokáže počas testov zhromažďovať informácie o type a na základe zhromaždených informácií môže do vášho kódu pridať anotácie typu. Obzvlášť rozšírené prijatie tohto nástroja sme však nezaznamenali. Zhromažďovanie informácií o type bolo pomalé a automaticky generované anotácie si často vyžadovali veľa manuálnych úprav. Uvažovali sme o automatickom spustení tohto nástroja vždy, keď kontrolujeme kód, alebo o zhromažďovaní informácií o type na základe analýzy nejakého malého objemu skutočných sieťových požiadaviek, ale rozhodli sme sa tak urobiť, pretože oba prístupy boli príliš riskantné.

V dôsledku toho je možné poznamenať, že väčšina kódu bola ručne anotovaná jeho vlastníkmi. Aby sme tento proces nasmerovali správnym smerom, pripravujeme správy o obzvlášť dôležitých moduloch a funkciách, ktoré je potrebné komentovať. Napríklad je dôležité poskytnúť anotácie typu pre modul knižnice, ktorý sa používa na stovkách miest. Ale starú službu, ktorá sa nahrádza novou, už nie je také dôležité komentovať. Tiež experimentujeme s použitím statickej analýzy na generovanie typových anotácií pre starý kód.

Cyklický dovoz. Vyššie som hovoril o cyklických importoch („spleťoch závislosti“), ktorých existencia sťažovala zrýchlenie mypy. Museli sme tiež tvrdo pracovať, aby mypy podporovali všetky druhy idiómov, ktoré sú spôsobené týmito cyklickými importmi. Nedávno sme dokončili veľký projekt redizajnu systému, ktorý vyriešil väčšinu problémov mypy týkajúcich sa obehového dovozu. Tieto problémy v skutočnosti pramenili z veľmi raných dní projektu, späť z Alore, vzdelávacieho jazyka, na ktorý bol projekt mypy pôvodne zameraný. Syntax Alore uľahčuje riešenie problémov s príkazmi cyklického importu. Moderný mypy zdedil určité obmedzenia zo svojej skoršej, jednoducho zmýšľajúcej implementácie (ktorá sa pre Alore veľmi hodila). Python sťažuje prácu s kruhovými importmi, najmä preto, že výrazy sú nejednoznačné. Napríklad operácia priradenia môže v skutočnosti definovať alias typu. Mypy nie je vždy schopný detekovať veci ako je tento, kým sa nespracuje väčšina importnej slučky. V Alore takéto nejasnosti neboli. Zlé rozhodnutia urobené v počiatočných fázach vývoja systému môžu o mnoho rokov neskôr predstavovať pre programátora nepríjemné prekvapenie.

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

Projekt mypy prešiel dlhou cestou – od prvých prototypov až po systém, ktorý riadi 4 milióny riadkov typov výrobných kódov. Ako sa mypy vyvíjal, rady typu Python boli štandardizované. V týchto dňoch sa okolo zadávania kódu Python vyvinul silný ekosystém. Má miesto pre podporu knižníc, obsahuje pomocné nástroje pre IDE a editory, má niekoľko typov riadiacich systémov, z ktorých každý má svoje klady a zápory.

Aj keď je kontrola typu v Dropboxe už samozrejmosťou, verím, že sme stále v začiatkoch písania kódu Python. Myslím si, že technológie typovej kontroly sa budú naďalej vyvíjať a zlepšovať.

Ak ste vo svojom rozsiahlom projekte v Pythone ešte nepoužili kontrolu typu, potom vedzte, že teraz je veľmi vhodný čas začať prechádzať na statické písanie. Hovoril som s tými, ktorí urobili podobný prechod. Nikto z nich to neoľutoval. Kontrola typu robí z Pythonu jazyk, ktorý je oveľa vhodnejší na vývoj veľkých projektov ako „bežný Python“.

Vážení čitatelia! Používate kontrolu typu vo svojich projektoch Python?

Cesta k typovej kontrole 4 miliónov riadkov kódu Python. Časť 3
Cesta k typovej kontrole 4 miliónov riadkov kódu Python. Časť 3

Zdroj: hab.com

Pridať komentár