Esitleme teile Dropboxi teekonna kolmandat osa, kuidas nad loobusid Python-koodi tüüpide kontrollimise süsteemist.
→ Eelnevad osad: ja
4 miljoni tüübitud koodi rida saavutamine
Teiseks oluliseks ülesandeks (see oli teiseks kõige populaarsem probleem, mis puudutas sisemisi uuringutes osalejaid) oli suurendada Dropboxis tüübid kontrolli alla langeva koodi mahtu. Katsetasime mitmeid lähenemisviise selle ülesande lahendamiseks - looduslikust kasvust tüübitud koodibaasi mahus kuni meeskonna mypy liikmete jõupingutuste suunamiseni staatilise ja dünaamilise automaatse tüübiväljundi poole. Tekkis mulje, et siin puudub lihtne võidustrateegia, kuid suutsime saavutada kiiret kasvu märgitud koodi mahtude osas, kombineerides mitmeid lähenemisviise.
Tulemuseks jõudis meie suurimas Python-repositooriumis (tagakoodi jaoks) märgitud koodi ridade arv peaaegu 4 miljoni ni. Koodi staatiline tüübistamine viidi läbi umbes kolme aasta jooksul. Mypy toetab nüüd erinevaid koodi katvuse aruanne, mis lihtsustavad tüübistamise jälgimist. Eelkõige suudame genereerida aruandeid koodi kohta, kus on ebamugavusi tüüpidega, näiteks selge tüübiga kasutuselemendid Any tüüpide annotatsioonides, mida ei saa kontrollida, või sellised, nagu kolmandate osade raamatukogude import, kus ei ole tüübide annotatsioone. Dropboxi tüübide kontrollimise täpsuse suurendamise projekti raames oleme panustanud mitmete populaarsete avatud lähtekoodiga raamatukogude tüübide määratlemise (nn stub-failide) parandamisse keskendunud Python-repositooriumis .
Olemes oleme rakendanud (ja standardiseerinud hilisemate PEP-ituse käigus) uusi tüübisüsteemi võimalusi, mis võimaldavad kasutada täpsemaid tüüpe teatud spetsiifiliste Python-mustrite jaoks. Silmapaistvaks näiteks on TypeDict, mis pakub tüüpe JSON-sarnastele sõnastikele, millel on fikseeritud hulk stringi võtmeid, kus igal on oma tüübi väärtus. Jätkame tübisüsteemi laiendamist. Tõenäoliselt on meie järgmine samm Python-i numbrite töötlemise võimekuse toetuse parandamine.

Annoteritud koodi ridade arv: server

Annotatud koodi ridade arv: klient

Annotatud koodi koguarv
Siin on ülevaade peamistest omadustest, mida oleme teinud, et suurendada annotatsioonide arvu Dropboxis:
Annotatsioonide rangus. Oleme järk-järgult suurendanud uusi koodi annotatsioonide ranguse nõudeid. Alustasime linteri soovitustega, milles soovitati lisada annotatsioone failidesse, kus juba on mõningad annotatsioonid. Nüüd nõuame, et uusis Python-failides oleksid tüüpide annotatsioonid ning enamikus olemasolevates failides.
Tüüpide raportid. Saadame iganädalasi aruandeid meeskondadele nende koodi tüüpide taseme kohta ja jagame näpunäiteid selle kohta, mida tuleks kõigepealt annotatsiooniks võtta.
Mypy populariseerimine. Tutvustame mypy-d erinevatel üritustel ja suhtleme meeskondadega, aidates neil alustada tüüpide annotatsioonide kasutamisega.
Küsimustikud. Kasutame perioodilisi küsimustikke, et tuvastada peamised probleemid. Oleme valmis minema otsustavalt kaugemale nende probleemide lahendamisel (kuni uue keele loomise vajaduseni mypy kiirendamiseks!).
Jõudlus. Oleme oluliselt parandanud mypy jõudlust, kasutades demonaid ja mypyc-d. See on tehtud selleks, et vähendada annotatsiooniprotsessis esinevaid ebamugavusi ja võimaldada tööd suuremate koodimahustega.
Toimetajate integreerimine. Oleme loonud tööriistad mypy käitamise toetamiseks Dropboxis populaarsetes toimetajates. Nendeks on PyCharm, Vim ja VS Code. See on oluliselt lihtsustanud koodi annotatsiooni ja selle töökindluse kontrollimise protsessi. Sellised tegevused on tavaliselt iseloomulikud olemasoleva koodi annotatsioonile.
Staatiline analüüs. Oleme loonud tööriista funktsioonide allkirjade genereerimiseks staatilise analüüsi abil. See tööriist töötab ainult suhteliselt lihtsates olukordades, kuid see aitas meil vaevata suurendada tüüpide katvust koodis.
Kolmandate osapoolte raamatukogude toetaminen. Paljusid meie projekte toetab SQLAlchemy tööriistade komplekt. See kasutab dünaamilisi Python'i võimalusi, mida PEP 484 tüübid ei suuda otse modelleerida. Vastavalt PEP 561 oleme loonud vastava stub-faili ja kirjutanud mypy jaoks plugina.), parandab SQLAlchemy tuge.
Kohtumised keerukustega
Teekond 4 miljoni rida tüübitud koodini ei olnud alati lihtne. Sellel teel kohtasime palju takistusi ja tegime mitmeid vigu. Siin on mõned probleemid, millega silmitsi seisisime. Loodame, et nende juurde pääsemine aitab teistel sarnastest probleemidest mööda minna.
Puuduolevad failid. Alustasime tööd vaid väikese hulga failide kontrollimisega. Midagi, mis ei kuulunud nende failide hulka, ei kontrollitud. Failid lisati kontrollimisnimekirja, kui neis ilmnesid esimesed annotatsioonid. Kui midagi imporditi moodulist, mis asub kontrollimise ulkest väljaspool, siis rääkisime tüüpide väärtustest, Any, mida üldse ei kontrollitud. See viis märkimisväärse tüübi täpsuse kadumiseni, eriti migreerimise varases etapis. See lähenemine töötas endiselt üllatavalt hästi, kuigi tüüpiline olukord oli see, et failide lisamine kontrollimisalasse paljastas probleeme koodi aluse teistes osades. Kõige halvemal juhul, kui kaks isoleeritud koodi valdkonda, kus tüübid olid juba sõltumatult kontrollitud, kokku pandi, selgus, et nende valdkondade tüübid ei olnud omavahel ühilduvad. See tõi kaasa vajaduse teha palju muudatusi annotatsioonides. Nüüd, tagasi vaadates, mõistame, et oleksime pidanud võimalikult varakult lisama mypy tüüpide kontrollimise alasse põhiraamatukogude moodulid. See oleks teinud meie töö palju ennustatavamaks.
Vanade koodide anoteerimine. Kui me alustasime, oli meil umbes 4 miljonit juba olemasolevat Python-koodi rida. Oli selge, et kogu selle koodi anoteerimine on keeruline ülesanne. Loome tööriista nimega PyAnnotate, mis suudab koguda tüübiandmeid töö ajal testide käigus ja suudab lisada koodile tüübiannotatsioone põhinedes kogutud andmetele. Kuid me ei ole märganud selle tööriista laialdast kasutuselevõttu. Tüübiandmete kogumine oli aeglane, automaatselt genereeritud annotatsioonid nõudsid sageli palju käsitsi parandusi. Me mõtleme automaatse käivitamise üle iga koodi kontrollimise ajal või tüübiandmete kogumise üle teatud väikese hulga tegelike võrgu päringute analüüsi põhjal, kuid otsustasime seda mitte teha, kuna mõlemad lähenemised on liiga riskantsed.
Kokkuvõttes võib märkida, et enamik koodist on käsitsi anoteeritud selle omanike poolt. Me, et suunata seda protsessi õiges suunas, valmistame ette aruandeid eriti olulistele moodulitele ja funktsioonidele, mis tuleb anoteerida. Näiteks on oluline varustada anoteeringutega tüübiandmeid raamatukogu moodul, mida kasutatakse sadades kohtades. Kuid vana teenuse anoteerimine, mida asendab uus, ei ole enam nii oluline. Me katsetame ka staatilise analüüsi kasutamist, et genereerida tüübiannotatsioone vana koodi jaoks.
Tsüklilised impordid. Ülalpool rääkisin tsüklilistest imporditest ("sõltuvuste klubid"), mille olemasolu on raskendanud mypy kiirendamist. Meil tuli peale selle ka tõsiselt vaeva näha, et varustada mypy kõigi nende idiomade toega, mille teke tuleneb just nendest tsüklilistest imporditest. Hiljuti lõpetasime ulatusliku süsteemi redigeerimise projekti, mis lahendas enamikku mypyga seotud tsükliliste impordite probleeme. Need probleemid tekkisid tegelikult juba projekti varajastes päevades, veel Alore'ist, õppimiskeelest, millele mypy algselt suunatud oli. Alore süntaks võimaldab tsükliliste impordite probleeme hõlpsasti lahendada. Kaasaegne mypy on pärinud osa piirangutest oma varasest lihtsast rakendusest (mis sobis Alore'ile suurepäraselt). Python muudab tsükliliste imporditega töötamise keerulisemaks peamiselt väljendite ebaselguse tõttu. Näiteks võib väärtuse määramise käigus tegelikult määratleda tüübi alias. Mypy ei suuda selliseid asju alati tuvastada, enne kui suurem osa impordi tsüklis on töödeldud. Alore'is ei esinenud selliseid ebaselgusi. Varaste süsteemi arendusetapid võetud ebaõnnestunud otsused võivad programmeerijale ebameeldiva üllatuse tuua palju aastaid hiljem.
Kokkuvõtted: tee 5 miljoni koodi realt ja uutele horison'tele
Mypy projekt on käinud pikka teed – varasest prototüüpide ajast kuni süsteemini, mis kontrollib 4 miljoni koodi rea tootmisstandardeid. Mypy arendamise käigus toimus Pythonis tüüpsignaalide standardimine. Tänapäeval on Python-koodi tüüpe ümbritseva tugeva ökosüsteemi ümber tekkinud. Seal leidub toetavaid teeke, IDE ja redigeerijate abivahendeid ning mitmeid tüübi kontrolli süsteeme, millest igal on oma plussid ja miinused.
Kuigi tüübi kontrolli peetakse Dropboxis juba iseenesest mõistetavaks, olen ma kindel, et me elame ikka veel Python-koodi tüpiseerimise alguses. Ma arvan, et tüübi kontrolli tehnoloogiad jätkavad arendamist ja täiustamist.
Kui te pole veel oma suurtes Python-projektides tüüpide kontrolli kasutanud, siis teadke, et praegu on ideaalne aeg alustada üleminekut staatilisele tüüpimisele. Olen rääkinud nendega, kes on sellise ülemineku teinud. Keegi neist ei ole kahetsenud. Tüüpide kontroll muudab Python'i keeleks, mis sobib palju paremini, kui "tavaline Python", suurte projektide arendamiseks.
Lugupeetud lugejad! Kasutate oma Python-projektides tüüpide kontrolli?
Allikas: habr.com
