Put do provjere tipa 4 milijuna linija Python koda. 3. dio

Predstavljamo vam treći dio prijevoda materijala o putu koji je Dropbox prošao prilikom implementacije sustava provjere tipa za Python kod.

Put do provjere tipa 4 milijuna linija Python koda. 3. dio

→ Prethodni dijelovi: prvo и drugi

Dosezanje 4 milijuna redaka tipkanog koda

Još jedan veliki izazov (i druga najčešća briga interno ispitanih) bilo je povećanje količine koda pokrivenog provjerama tipa u Dropboxu. Isprobali smo nekoliko pristupa rješavanju ovog problema, od prirodnog povećanja veličine unesene baze koda do fokusiranja napora mypy tima na statičko i dinamičko automatsko zaključivanje tipa. Na kraju se činilo da nema jednostavne pobjedničke strategije, ali uspjeli smo postići brzi rast količine označenog koda kombinirajući mnoge pristupe.

Kao rezultat toga, naše najveće Python spremište (s pozadinskim kodom) ima gotovo 4 milijuna redaka označenog koda. Radovi na statičkom tipiziranju koda završeni su za otprilike tri godine. Mypy sada podržava različite vrste izvješća o pokrivenosti koda koji olakšavaju praćenje napretka tipkanja. Konkretno, možemo generirati izvješća o kodu s dvosmislenostima u tipovima, kao što je, na primjer, eksplicitna upotreba tipa Any u primjedbama koje se ne mogu provjeriti ili sa stvarima poput uvoza biblioteka trećih strana koje nemaju primjedbe tipa. Kao dio projekta za poboljšanje točnosti provjere tipa u Dropboxu, pridonijeli smo poboljšanju definicija tipa (tzv. stub datoteke) za neke popularne biblioteke otvorenog koda u centraliziranom Python repozitoriju tipkalo.

Implementirali smo (i standardizirali u sljedećim PEP-ovima) nove značajke sustava tipova koje omogućuju preciznije tipove za neke specifične Python obrasce. Značajan primjer za to je TypeDict, koji pruža tipove za rječnike slične JSON-u koji imaju fiksni skup nizovnih ključeva, svaki s vrijednošću vlastitog tipa. Nastavit ćemo širiti sustav tipova. Naš sljedeći korak vjerojatno će biti poboljšanje podrške za numeričke mogućnosti Pythona.

Put do provjere tipa 4 milijuna linija Python koda. 3. dio
Broj redaka označenog koda: poslužitelj

Put do provjere tipa 4 milijuna linija Python koda. 3. dio
Broj redaka označenog koda: klijent

Put do provjere tipa 4 milijuna linija Python koda. 3. dio
Ukupan broj redaka označenog koda

Evo pregleda glavnih značajki stvari koje smo učinili kako bismo povećali količinu označenog koda u Dropboxu:

Strogost primjedbi. Postupno smo povećavali zahtjeve za rigoroznošću označavanja novog koda. Započeli smo sa savjetima za linter koji su sugerirali dodavanje komentara datotekama koje su već imale neke komentare. Sada zahtijevamo komentare tipa u novim Python datotekama i u većini postojećih datoteka.

Tipkanje izvješća. Šaljemo timovima tjedna izvješća o razini upisivanja koda i dajemo savjete o tome što bi prvo trebalo označiti.

Popularizacija mypyja. Razgovaramo o mypy na događajima i razgovaramo s timovima kako bismo im pomogli da počnu s primjedbama tipa.

Ankete. Provodimo periodične ankete korisnika kako bismo identificirali glavne probleme. Spremni smo ići prilično daleko u rješavanju ovih problema (čak i stvoriti novi jezik za ubrzavanje mypy!).

Izvođenje. Uvelike smo poboljšali izvedbu mypyja korištenjem demona i mypyca. To je učinjeno kako bi se izgladile neugodnosti koje nastaju tijekom procesa označavanja i kako bi se mogao raditi s velikim količinama koda.

Integracija s urednicima. Napravili smo alate za podršku pokretanja mypyja u uređivačima koji su popularni na Dropboxu. To uključuje PyCharm, Vim i VS Code. Ovo je uvelike pojednostavilo proces označavanja koda i provjere njegove funkcionalnosti. Ove vrste radnji uobičajene su prilikom označavanja postojećeg koda.

Statička analiza. Napravili smo alat za zaključivanje potpisa funkcija pomoću alata za statičku analizu. Ovaj alat može raditi samo u relativno jednostavnim situacijama, ali nam je pomogao da povećamo pokrivenost tipa koda bez puno truda.

Podrška za biblioteke trećih strana. Mnogi naši projekti koriste SQLAlchemy toolkit. Iskorištava prednosti dinamičkih mogućnosti Pythona koje vrste PEP 484 ne mogu izravno modelirati. Mi smo, u skladu s PEP 561, kreirali odgovarajuću stub datoteku i napisali dodatak za mypy (otvoreni izvor), što poboljšava podršku za SQLAlchemy.

Poteškoće na koje smo naišli

Put do 4 milijuna redaka tipkanog koda nije nam uvijek bio lak. Na ovoj smo stazi naišli na mnoge rupe i napravili nekoliko grešaka. Ovo su neki od problema s kojima smo se susreli. Nadamo se da će pričanje o njima pomoći drugima da izbjegnu slične probleme.

Nedostaju datoteke. Započeli smo s radom provjerom samo male količine datoteka. Sve što nije uključeno u ove datoteke nije provjereno. Datoteke su dodane na popis za skeniranje kada su se u njima pojavile prve zabilješke. Ako je nešto uvezeno iz modula koji se nalazi izvan opsega provjere, tada smo govorili o radu s vrijednostima poput Any, koji uopće nisu testirani. To je dovelo do značajnog gubitka točnosti tipkanja, posebno u ranim fazama migracije. Ovaj je pristup do sada funkcionirao iznenađujuće dobro, iako je tipična situacija da dodavanje datoteka u opseg pregleda otkriva probleme u drugim dijelovima baze koda. U najgorem slučaju, kada su spojena dva izolirana područja koda, u kojima su tipovi već bili provjereni neovisno jedno o drugom, pokazalo se da su tipovi tih područja međusobno nekompatibilni. To je dovelo do potrebe za uvođenjem mnogih izmjena u komentare. Gledajući sada unatrag, shvaćamo da smo trebali dodati osnovne module knjižnice u mypyjevo područje provjere tipa ranije. To bi naš rad učinilo mnogo predvidljivijim.

Označavanje starog koda. Kad smo počeli, imali smo oko 4 milijuna redaka postojećeg Python koda. Bilo je jasno da označavanje cijelog tog koda nije lak zadatak. Napravili smo alat pod nazivom PyAnnotate koji može prikupljati informacije o tipu dok se testovi izvode i može dodati komentare tipa vašem kodu na temelju prikupljenih informacija. Međutim, nismo primijetili posebno široku primjenu ovog alata. Prikupljanje informacija o vrsti bilo je sporo, a automatski generirane zabilješke često su zahtijevale mnogo ručnih izmjena. Razmišljali smo o automatskom pokretanju ovog alata svaki put kada pregledavamo kôd ili prikupljanju informacija o vrsti na temelju analize neke male količine stvarnih mrežnih zahtjeva, ali odlučili smo da to nećemo učiniti jer je oba pristupa previše riskantna.

Kao rezultat toga, može se primijetiti da su većinu koda njegovi vlasnici ručno označili. Kako bismo vodili ovaj proces u pravom smjeru, pripremamo izvješća o posebno važnim modulima i funkcijama koje je potrebno označiti. Na primjer, važno je osigurati tipske bilješke za modul knjižnice koji se koristi na stotinama mjesta. Ali stara usluga koja se zamjenjuje novom više nije toliko važna za označavanje. Također eksperimentiramo s korištenjem statičke analize za generiranje tipskih komentara za naslijeđeni kod.

Ciklični uvozi. Gore sam govorio o cikličkim uvozima ("zapletima ovisnosti"), čije je postojanje otežavalo ubrzanje mypyja. Također smo morali naporno raditi kako bi mypy podržavao sve vrste idioma koji su uzrokovani ovim cikličkim uvozom. Nedavno smo dovršili veliki projekt redizajna sustava koji je riješio većinu mypyjevih problema u vezi s kružnim uvozom. Ovi su problemi zapravo proizašli iz ranih dana projekta, još iz Alorea, obrazovnog jezika na koji je mypy projekt izvorno bio fokusiran. Alore sintaksa olakšava rješavanje problema s cikličkim uvoznim naredbama. Moderni mypy naslijedio je neka ograničenja od svoje ranije, jednostavne implementacije (koja je bila sjajna za Alore). Python otežava rad s kružnim uvozima, uglavnom zato što su izrazi dvosmisleni. Na primjer, operacija dodjele može zapravo definirati alias tipa. Mypy nije uvijek u stanju otkriti ovakve stvari dok se većina petlje uvoza ne obradi. U Aloreu nije bilo takvih nejasnoća. Loše odluke donesene u ranim fazama razvoja sustava mogu predstavljati neugodno iznenađenje programeru mnogo godina kasnije.

Rezultati: put do 5 milijuna redaka koda i novi horizonti

Projekt mypy prošao je dug put - od ranih prototipova do sustava koji kontrolira 4 milijuna linija tipova proizvodnog koda. Kako se mypy razvijao, Pythonovi tipovi su standardizirani. Ovih se dana razvio snažan ekosustav oko upisivanja Python koda. Ima mjesto za podršku knjižnici, sadrži pomoćne alate za IDE i urednike, ima nekoliko sustava kontrole tipa, od kojih svaki ima svoje prednosti i nedostatke.

Iako je provjera tipa već zadana u Dropboxu, vjerujem da smo još uvijek u ranim danima upisivanja Python koda. Mislim da će se tehnologije provjere tipa nastaviti razvijati i poboljšavati.

Ako još niste koristili provjeru tipa u svom velikom Python projektu, znajte da je sada jako dobro vrijeme da počnete prelaziti na statično tipkanje. Razgovarao sam s onima koji su napravili sličnu tranziciju. Nitko od njih nije požalio. Provjera tipa čini Python jezikom koji je mnogo prikladniji za razvoj velikih projekata od "običnog Pythona".

Dragi čitatelji! Koristite li provjeru tipa u svojim Python projektima?

Put do provjere tipa 4 milijuna linija Python koda. 3. dio
Put do provjere tipa 4 milijuna linija Python koda. 3. dio

Izvor: www.habr.com

Dodajte komentar