Iepriekš jūs iepazīstinājām ar trešo daļu par to, kā uzņēmums Dropbox ieviesa Python koda tipu pārbaudes sistēmu.
→ Iepriekšējās daļas: un
Četri miljoni tipētā koda rindiņu
Vēl viena būtiska problēma (kas bija otrā populārākā problēma, ko uzdeva iekšējie aptauju dalībnieki) bija palielināt Dropbox kodu apjomu, kas segts ar tipu pārbaudēm. Mēs izmēģinājām vairākus pieejas šīs problēmas risināšanai — no dabīga tipētā koda bāzes pieauguma līdz mypy komandas centieniem koncentrēties uz statisko un dinamisko tipa automātisko izsviešanu. Rezultātā radās iespaids, ka nav vienkāršas uzvarētājas stratēģijas, taču mēs spējām ātri palielināt anotēta koda apjomu, apvienojot daudzus piegājienus.
Rezultātā mūsu lielākajā Python repozitorijā (ar backend kodu) anotētā koda rindiņu skaits sasniedza gandrīz 4 miljonus. Darbs pie koda statiskās tipizācijas tika paveikts aptuveni trīs gadu laikā. Mypy tagad atbalsta dažādus kodu segšanas tipo ziņojumus, kas atvieglo tipizācijas uzraudzību. Īpaši mēs varam veidot ziņojumus par kodu ar nenoteiktībām tipos, piemēram, par skaidru tipa izmantošanu Any anotācijās, kuras nav iespējams pārbaudīt, vai par trešo pušu bibliotēku importu, kurām nav tipu anotāciju. Projekta ietvaros, lai uzlabotu tipu pārbaudes precizitāti Dropbox, mēs ieguldījām, lai uzlabotu tipu definīcijas (saukta par stub failiem) dažādām populārām atvērtā koda bibliotēkām centralizētajā Python repozitorijā .
Mēs īstenojām (un standartizējām turpmākajos PEP) jaunas tipu sistēmas iespējas, kas ļauj izmantot precīzākus tipus dažām specifiskām Python paraugām. Ievērojams piemērs tam ir TypeDict, kas nodrošina tipus JSON līdzīgiem vārdnīcām, kurām ir fiksēts virkņu atslēgu kopums, katrai no kurām ir sava tipa vērtība. Mēs turpināsim paplašināt tipu sistēmu. Iespējams, mūsu nākamais solis būs uzlabot atbalstu Python skaitļu apstrādes iespējām.

Anotētā koda rindiņu skaits: server

Anotētā koda rindu skaits: klients

Kopējais anotētā koda rindu skaits
Šeit ir galveno iezīmju pārskats par darbībām, ko veicām, lai palielinātu anotētā koda apjomu Dropbox:
Anotācijas stingrība. Mēs pakāpeniski paaugstinājām prasības attiecībā uz jaunā koda anotēšanu. Mēs sākām ar lintera ieteikumiem, kas ierosināja pievienot anotācijas failiem, kuros jau ir dažas anotācijas. Tagad mēs prasām tipu anotācijas jaunajos Python failos un lielākajā daļā esošo failu.
Tīpa ziņojumi. Mēs katru nedēļu sūtām komandām ziņojumus par viņu koda tipa līmeni un sniedzam ieteikumus par to, kas būtu jāanotē vispirms.
Mypy popularizēšana. Mēs stāstām par mypy dažādos pasākumos un sazināmies ar komandām, palīdzot viņiem sākt izmantot tipu anotācijas.
Aptaujas. Mēs veicam periodiskas lietotāju aptaujas, lai identificētu galvenās problēmas. Mēs esam gatavi iet pietiekami tālu, lai risinātu šīs problēmas (pat veidojot jaunu valodu mypy paātrināšanai!).
Veiktspēja. Mēs ievērojami uzlabojām mypy veiktspēju, izmantojot deamonu un mypyc. Tas tika izdarīts, lai mazinātu neērtības, kas rodas anotēšanas procesā, un lai būtu iespējams strādāt ar lieliem koda apjomiem.
Integrācija ar redaktoriem. Mēs izveidojām rīkus, lai atbalstītu mypy palaišanu populāros redaktoros, ko izmanto Dropbox. Tajā ietilpst PyCharm, Vim un VS Code. Tas ievērojami atviegloja koda anotēšanas un tā darbspēju pārbaudes procesu. Šādas darbības parasti ir raksturīgas esoša koda anotēšanai.
Statiskā analīze. Mēs izveidojām rīku funkciju parakstu izvadīšanai, izmantojot statisko analīzi. Šis rīks var darboties tikai salīdzinoši vienkāršās situācijās, bet tas palīdzēja mums bez lielām grūtībām palielināt tipu pārklājumu koda pusē.
Trešo pušu bibliotēku atbalsts. Daudzos mūsu projektos tiek izmantots SQLAlchemy rīku komplekts. Tajā tiek izmantotas Python dinamiskās iespējas, kuras PEP 484 tipi nespēj tieši modelēt. Mēs, saskaņā ar PEP 561, izveidojām atbilstošu stub failu un uzrakstījām mypy spraudni (), uzlabojot SQLAlchemy atbalstu.
Grūtības, ar kurām saskārāmies
Ceļš uz 4 miljoniem tipizēta koda rindiņu nebija vienmēr viegls. Šajā procesā saskārāmies ar daudzām grūtībām un izdarījām vairākas kļūdas. Lūk, dažas no problēmām, ar kurām mēs sastapāmies. Ceram, ka stāsts par tām palīdzēs citiem izvairīties no līdzīgām situācijām.
Palaistie faili. Mēs uzsākām darbu ar nelielu failu skaita pārbaudi. Viss, kas neietilpa šajos failos, netika pārbaudīts. Faili pārbaudei tika pievienoti tikai tad, kad tajos parādījās pirmie komentāri. Ja kaut kas tika importēts no moduļa, kas atradās ārpus pārbaudes jomas, tas attiecās uz vērtību veidiem Any, kuri vispār netika pārbaudīti. Tas noveda pie būtiskas tipizēšanas precizitātes zuduma, īpaši - pārejas sākumposmā. Šāds piegājiens joprojām pārsteidzoši labi darbojās, lai gan tipiska situācija bija, kad failu pievienošana pārbaudes jomai izcēla problēmas citās kodēšanas bāzes daļās. Sliktākajā gadījumā, kad tika apvienotas divas izolētas koda jomas, kurās neatkarīgi bija pārbaudīti tipi, izrādījās, ka šo jomu tipi nav savietojami. Tas prasīja veikt daudzus grozījumus anotācijās. Tagad, atskatoties, mēs saprotam, ka būtu bijis jāizdara vismazākā izvēle un jāpievieno mypy veidu pārbaudei pamata bibliotēku moduļi. Tas padarītu mūsu darbu daudz prognozējamāku.
Vecā koda anotācija. Kad mēs sākām strādāt, mums bija apmēram 4 miljoni rindu jau esoša Python koda. Bija skaidrs, ka visu šo kodu anotēt — nav viegla uzdevums. Mēs izstrādājām rīku, ko nosaucām par PyAnnotate, kurš spēj vākt informāciju par tipiem, veicot testu laikā, un pievienot tipa anotācijas kodam, pamatojoties uz vāktajām ziņām. Tomēr mēs nenovērojām plašu šī rīka ieviešanu. Informācijas vākšana par tipiem bija lēna, automātiski ģenerētās anotācijas bieži prasīja daudz roku labojumu. Mēs domājām par automātiskas šā rīka palaišanu katras koda pārbaudes laikā vai par informācijas vākšanu par tipiem, pamatojoties uz analīzi no neliela reālu tīkla pieprasījumu apjoma, bet izlēmām to nedarīt, jo kāds no šiem piegājieniem bija pārāk riskants.
Galu galā var atzīmēt, ka lielākā daļa koda tika manuāli anotēta tās īpašnieku. Mēs, lai virzītu šo procesu pareizajā virzienā, gatavojam ziņojumus par īpaši svarīgajiem moduļiem un funkcijām, kas jāanotē. Piemēram, ir svarīgi nodrošināt tipa anotācijas bibliotēku modulim, kas tiek izmantots simtiem vietu. Savukārt veco pakalpojumu, kuru nomaina jauns, vairs nav tik svarīgi anotēt. Mēs arī eksperimentiējam ar statiskā analīzes izmantošanu, lai ģenerētu tipa anotācijas vecajam kodam.
Cikliskie importi. Iepriekš es runāju par cikliskajiem importiem (par «atkarību klubiem»), kuru esamība apgrūtināja mypy paātrināšanu. Mums bija jāveic nopietns darbs, lai nodrošinātu mypy atbalstu visām idiomām, kas rodas šo ciklisko importu dēļ. Nesen mēs pabeidzām lielu sistēmas pārdizaina projektu, kas novērsa lielāko daļu mypy problēmu saistībā ar cikliskajiem importiem. Šīs problēmas, patiesībā, radās jau projekts sākuma posmos, vēl no Alore, mācību valodas, uz kuru sākotnēji tika orientēts mypy projekts. Alore sintakse ļauj viegli risināt ciklisko importa komandu problēmas. Mūsdienu mypy ir mantojis dažus ierobežojumus no savas agrīnās, vienkāršās realizācijas (kas bija lieliski piemērota Alore). Python apgrūtina darbu ar cikliskajiem importiem galvenokārt neskaidrības dēļ izteikumos. Piemēram, vērtības piešķiršanas operācijas laikā var faktiskā tikt noteikts tipu psevdonīms. Mypy ne vienmēr spēj identificēt šādas lietas, līdz lielākā daļa importa cikla nav apstrādāta. Alore šādu neskaidrību nebija. Agrīnos attīstības posmos pieņemtie neizdodas risinājumi var programmētājam sagādāt nepatīkamu pārsteigumu pēc daudzām gadiem.
Secinājumi: ceļš uz 5 miljoniem koda rindiņu un jauniem apvāršņiem
Mypy projekts ir gājis garu ceļu — no agrīniem prototipiem līdz sistēmai, kas kontrolē ražošanas koda tipus apjomā 4 miljoni rindiņu. Mypy attīstības gaitā tika standartizētas tipu norādījumi Python valodā. Mūsdienās apkārt Python koda tipu norādījumiem ir izveidojusies spēcīga ekosistēma. Tajā ir vieta bibliotēku atbalstam, pieejami ir rīki IDE un redaktoriem, un tajā ir vairākas tipu kontroles sistēmas, katrai no kurām ir savi plusi un mīnusi.
Neskatoties uz to, ka tipu pārbaude Dropbox jau tiek uztverta kā kaut kas pašsaprotams, es esmu pārliecināts, ka mēs vēl joprojām dzīvojam Python koda tipu ziedu laikmetā. Es domāju, ka tipu pārbaudes tehnoloģijas turpinās attīstīties un uzlaboties.
Ja, ja vēl neesat izmantojuši tipu pārbaudi savā plaša mēroga Python projektā, tad ziniet, ka tagad ir ļoti piemērots laiks sākt pāreju uz statisko tipizāciju. Esmu runājis ar tiem, kas veikuši šādu pāreju. Neviens no viņiem to nenožēloja. Tipu kontrole padara Python par valodu, kas daudz labāk atbilst lielu projektu izstrādei nekā "parastais Python".
Cienījamie lasītāji! Vai jūs izmantojat tipu kontroli savos Python projektos?
Avots: habr.com
