Cesta ke kontrole typu 4 milionů řádků kódu Pythonu. Část 3

Předkládáme vaší pozornosti třetí část překladu materiálu o cestě, kterou se Dropbox vydal při implementaci systému kontroly typu pro kód Python.

Cesta ke kontrole typu 4 milionů řádků kódu Pythonu. Část 3

→ Předchozí díly: první и druhý

Dosažení 4 milionů řádků napsaného kódu

Dalším velkým problémem (a druhým nejčastějším problémem mezi interně dotazovanými) bylo zvýšení množství kódu pokrytého typovými kontrolami v Dropboxu. Vyzkoušeli jsme několik přístupů k vyřešení tohoto problému, od přirozeného růstu velikosti typované kódové základny až po zaměření úsilí týmu mypy na statické a dynamické automatické odvození typu. Nakonec se zdálo, že neexistuje žádná jednoduchá vítězná strategie, ale díky kombinaci mnoha přístupů jsme byli schopni dosáhnout rychlého růstu objemu anotovaného kódu.

Výsledkem je, že naše největší úložiště Pythonu (s backendovým kódem) má téměř 4 miliony řádků anotovaného kódu. Práce na psaní statického kódu byly dokončeny přibližně za tři roky. Mypy nyní podporuje různé typy zpráv o pokrytí kódu, které usnadňují sledování průběhu psaní. Zejména můžeme generovat zprávy o kódu s nejednoznačnostmi v typech, jako je například explicitní použití typu Any v anotacích, které nelze ověřit, nebo s věcmi, jako je import knihoven třetích stran, které nemají typové anotace. V rámci projektu na zlepšení přesnosti kontroly typů v Dropboxu jsme přispěli ke zlepšení definic typů (tzv. stub files) pro některé oblíbené open source knihovny v centralizovaném úložišti Pythonu. typizovaný.

Implementovali jsme (a standardizovali v následujících PEP) nové funkce typového systému, které umožňují přesnější typy pro některé specifické vzory Pythonu. Pozoruhodným příkladem toho je TypeDict, který poskytuje typy pro slovníky podobné JSON, které mají pevnou sadu řetězcových klíčů, z nichž každý má hodnotu svého vlastního typu. Typový systém budeme nadále rozšiřovat. Naším dalším krokem bude pravděpodobně zlepšení podpory numerických schopností Pythonu.

Cesta ke kontrole typu 4 milionů řádků kódu Pythonu. Část 3
Počet řádků anotovaného kódu: server

Cesta ke kontrole typu 4 milionů řádků kódu Pythonu. Část 3
Počet řádků anotovaného kódu: klient

Cesta ke kontrole typu 4 milionů řádků kódu Pythonu. Část 3
Celkový počet řádků anotovaného kódu

Zde je přehled hlavních funkcí věcí, které jsme udělali, abychom zvýšili množství anotovaného kódu v Dropboxu:

Přísnost anotace. Postupně jsme zvyšovali požadavky na přísnost anotování nového kódu. Začali jsme s linterovými tipy, které navrhovaly přidat anotace k souborům, které již nějaké anotace měly. Nyní požadujeme typové anotace v nových souborech Pythonu a ve většině existujících souborů.

Psaní zpráv. Týmům zasíláme týdenní zprávy o úrovni psaní jejich kódu a poskytujeme rady, co by mělo být anotováno jako první.

Popularizace mypy. O mypy mluvíme na akcích a mluvíme s týmy, abychom jim pomohli začít s typovými anotacemi.

Ankety. Provádíme pravidelné uživatelské průzkumy, abychom identifikovali hlavní problémy. Jsme připraveni zajít v řešení těchto problémů docela daleko (dokonce i vytvořením nového jazyka pro urychlení mypy!).

Výkon. Výrazně jsme zlepšili výkon mypy použitím démona a mypyc. Bylo to provedeno proto, aby se vyrovnaly nepříjemnosti, které vznikají během procesu anotace, a aby bylo možné pracovat s velkým množstvím kódu.

Integrace s editory. Vytvořili jsme nástroje pro podporu spouštění mypy v editorech, které jsou oblíbené na Dropboxu. To zahrnuje PyCharm, Vim a VS Code. To značně zjednodušilo proces anotování kódu a kontroly jeho funkčnosti. Tyto typy akcí jsou běžné při anotaci existujícího kódu.

Statická analýza. Vytvořili jsme nástroj pro odvození signatur funkcí pomocí nástrojů statické analýzy. Tento nástroj může fungovat pouze v relativně jednoduchých situacích, ale pomohl nám zvýšit pokrytí typů kódu bez velkého úsilí.

Podpora knihoven třetích stran. Mnoho našich projektů používá sadu nástrojů SQLAlchemy. Využívá dynamických schopností Pythonu, které typy PEP 484 nejsou schopny přímo modelovat. V souladu s PEP 561 jsme vytvořili odpovídající stub soubor a napsali plugin pro mypy (open source), což zlepšuje podporu SQLAlchemy.

Potíže, se kterými jsme se setkali

Cesta ke 4 milionům řádků napsaného kódu pro nás nebyla vždy jednoduchá. Na této cestě jsme narazili na mnoho výmolů a udělali několik chyb. Toto jsou některé z problémů, se kterými jsme se setkali. Doufáme, že vyprávění o nich pomůže ostatním vyhnout se podobným problémům.

Chybějící soubory. Svou práci jsme zahájili kontrolou pouze malého množství souborů. Cokoli, co není zahrnuto v těchto souborech, nebylo zkontrolováno. Soubory byly přidány do seznamu skenování, když se v nich objevily první anotace. Pokud bylo něco importováno z modulu umístěného mimo rozsah ověření, pak jsme mluvili o práci s hodnotami jako Any, které nebyly vůbec testovány. To vedlo ke značné ztrátě přesnosti psaní, zejména v raných fázích migrace. Tento přístup zatím fungoval překvapivě dobře, ačkoli typická situace je, že přidání souborů do rozsahu recenze odhalí problémy v jiných částech kódové základny. V nejhorším případě, kdy došlo ke sloučení dvou izolovaných oblastí kódu, ve kterých již byly nezávisle na sobě kontrolovány typy, se ukázalo, že typy těchto oblastí jsou navzájem nekompatibilní. To vedlo k nutnosti provést mnoho změn v anotacích. Když se nyní ohlédneme zpět, uvědomíme si, že jsme měli do oblasti kontroly typu mypy přidat moduly základních knihoven dříve. Díky tomu by byla naše práce mnohem předvídatelnější.

Anotace starého kódu. Když jsme začínali, měli jsme asi 4 miliony řádků existujícího kódu Pythonu. Bylo jasné, že anotovat celý tento kód není snadný úkol. Vytvořili jsme nástroj nazvaný PyAnnotate, který dokáže shromažďovat informace o typu při běhu testů a na základě shromážděných informací může do vašeho kódu přidávat typové anotace. Zvláště rozšířené přijetí tohoto nástroje jsme však nezaznamenali. Shromažďování informací o typu bylo pomalé a automaticky generované anotace často vyžadovaly mnoho ručních úprav. Přemýšleli jsme o automatickém spuštění tohoto nástroje pokaždé, když kontrolujeme kód, nebo o shromažďování informací o typu na základě analýzy malého množství skutečných síťových požadavků, ale rozhodli jsme se tak, protože oba přístupy byly příliš riskantní.

V důsledku toho lze poznamenat, že většina kódu byla ručně anotována jeho vlastníky. Abychom tento proces nasměrovali správným směrem, připravujeme zprávy o zvláště důležitých modulech a funkcích, které je třeba komentovat. Například je důležité poskytnout typové anotace pro modul knihovny, který se používá na stovkách míst. Ale starou službu, která se nahrazuje novou, již není tak důležité komentovat. Experimentujeme také s použitím statické analýzy ke generování typových anotací pro starší kód.

Cyklické dovozy. Výše jsem mluvil o cyklických importech („spletence závislostí“), jejichž existence ztěžovala urychlení mypy. Také jsme museli tvrdě pracovat, aby mypy podporovaly všechny druhy idiomů, které jsou způsobeny těmito cyklickými importy. Nedávno jsme dokončili velký projekt redesignu systému, který vyřešil většinu problémů mypy týkajících se cyklických importů. Tyto problémy ve skutečnosti pramenily z velmi raných dnů projektu, zpět z Alore, vzdělávacího jazyka, na který byl projekt mypy původně zaměřen. Syntaxe Alore usnadňuje řešení problémů s příkazy cyklického importu. Moderní mypy zdědil některá omezení ze své dřívější, jednoduché implementace (která se pro Alore skvěle hodila). Python ztěžuje práci s kruhovými importy, hlavně proto, že výrazy jsou nejednoznačné. Například operace přiřazení může ve skutečnosti definovat alias typu. Mypy není vždy schopen takové věci detekovat, dokud není zpracována většina importní smyčky. V Alore žádné takové nejasnosti nebyly. Špatná rozhodnutí učiněná v raných fázích vývoje systému mohou o mnoho let později představovat pro programátora nepříjemné překvapení.

Výsledky: cesta k 5 milionům řádků kódu a novým obzorům

Projekt mypy ušel dlouhou cestu – od raných prototypů k systému, který řídí 4 miliony řádků typů výrobního kódu. Jak se mypy vyvíjel, byly typové rady Pythonu standardizovány. V těchto dnech se kolem psaní kódu Python vyvinul mocný ekosystém. Má místo pro podporu knihoven, obsahuje pomocné nástroje pro IDE a editory, má několik typů řídicích systémů, z nichž každý má své klady a zápory.

I když je kontrola typu již v Dropboxu samozřejmostí, věřím, že jsme stále v začátcích psaní kódu Python. Myslím, že technologie kontroly typu se budou nadále vyvíjet a zlepšovat.

Pokud jste ve svém rozsáhlém projektu v Pythonu ještě nepoužili kontrolu typu, pak vězte, že nyní je velmi vhodný čas začít přejít na statické psaní. Mluvil jsem s těmi, kteří provedli podobný přechod. Nikdo z nich toho nelitoval. Kontrola typu dělá z Pythonu jazyk, který je mnohem vhodnější pro vývoj velkých projektů než „běžný Python“.

Vážení čtenáři! Používáte kontrolu typu ve svých projektech Python?

Cesta ke kontrole typu 4 milionů řádků kódu Pythonu. Část 3
Cesta ke kontrole typu 4 milionů řádků kódu Pythonu. Část 3

Zdroj: www.habr.com

Přidat komentář