Å odien mÄs piedÄvÄjam jÅ«su uzmanÄ«bai pirmo daļu no materiÄla par to, kÄ Dropbox nodarbojas ar Python koda tipa kontroli.
Dropbox daudz raksta Python. Å Ä« ir valoda, ko mÄs izmantojam ļoti plaÅ”i ā gan aizmugures pakalpojumiem, gan darbvirsmas klientu lietojumprogrammÄm. MÄs arÄ« daudz lietojam Go, TypeScript un Rust, bet Python ir mÅ«su galvenÄ valoda. Å emot vÄrÄ mÅ«su mÄrogu, un mÄs runÄjam par miljoniem Python koda rindu, izrÄdÄ«jÄs, ka Å”Äda koda dinamiskÄ rakstÄ«Å”ana nevajadzÄ«gi sarežģīja tÄ izpratni un sÄka nopietni ietekmÄt darba ražīgumu. Lai mazinÄtu Å”o problÄmu, esam sÄkuÅ”i pakÄpeniski pÄrvietot savu kodu uz statisko tipa pÄrbaudi, izmantojot mypy. Å Ä«, iespÄjams, ir vispopulÄrÄkÄ Python atseviŔķa tipa pÄrbaudes sistÄma. Mypy ir atvÄrtÄ koda projekts, tÄ galvenie izstrÄdÄtÄji strÄdÄ Dropbox.
Dropbox bija viens no pirmajiem uzÅÄmumiem, kas ieviesa statisko tipa pÄrbaudi Python kodÄ Å”ÄdÄ mÄrogÄ. MÅ«sdienÄs Mypy tiek izmantots tÅ«kstoÅ”iem projektu. Å is rÄ«ks, kÄ saka, ir neskaitÄmas reizes āpÄrbaudÄ«ts kaujÄā. Mums bija jÄnoiet garÅ” ceļŔ, lai nokļūtu tur, kur esam tagad. Pa ceļam ir bijuÅ”i daudzi neveiksmÄ«gi centieni un neveiksmÄ«gi eksperimenti. Å ajÄ rakstÄ ir aprakstÄ«ta Python statiskÄs tipa pÄrbaudes vÄsture, sÄkot no tÄs klinÅ”ainajiem pirmsÄkumiem kÄ daļa no mana akadÄmiskÄ izpÄtes projekta lÄ«dz mÅ«sdienÄm, kad tipa pÄrbaudes un tipa mÄjieni ir kļuvuÅ”i par ierastu parÄdÄ«bu neskaitÄmu Python izstrÄdÄtÄju vidÅ«. Å os mehÄnismus tagad atbalsta dažÄdi rÄ«ki, piemÄram, IDE un kodu analizatori.
KÄpÄc ir nepiecieÅ”ama tipa pÄrbaude?
Ja kÄdreiz esat izmantojis dinamiski drukÄtu Python, jÅ«s varÄtu bÅ«t nedaudz neizpratnÄ par to, kÄpÄc pÄdÄjÄ laikÄ ir bijis tik daudz satraukumu par statisko rakstÄ«Å”anu un mypy. Vai arÄ« var gadÄ«ties, ka Python jums patÄ«k tieÅ”i tÄ dinamiskÄs rakstÄ«Å”anas dÄļ, un notiekoÅ”ais jÅ«s vienkÄrÅ”i apbÄdina. StatiskÄs rakstÄ«Å”anas vÄrtÄ«bas atslÄga ir lÄmumu mÄrogs: jo lielÄks ir jÅ«su projekts, jo vairÄk jÅ«s sliecaties uz statisko rakstÄ«Å”anu un galu galÄ, jo vairÄk jums tas patieÅ”Äm ir vajadzÄ«gs.
PieÅemsim, ka projekts ir sasniedzis desmitiem tÅ«kstoÅ”u lÄ«niju lielumu, un izrÄdÄs, ka pie tÄ strÄdÄ vairÄki programmÄtÄji. Apsverot Å”Ädu projektu, pamatojoties uz mÅ«su pieredzi, mÄs varam teikt, ka tÄ koda izpratne bÅ«s atslÄga izstrÄdÄtÄja produktivitÄtes uzturÄÅ”anai. Bez tipa anotÄcijÄm var bÅ«t grÅ«ti izdomÄt, piemÄram, kÄdi argumenti jÄnodod funkcijai vai kÄda veida vÄrtÄ«bas noteikta funkcija var atgriezt. Å eit ir tipiski jautÄjumi, uz kuriem bieži ir grÅ«ti atbildÄt, neizmantojot veida anotÄcijas:
- Vai Ŕī funkcija var atgriezties
None
? - KÄdam vajadzÄtu bÅ«t Å”im argumentam?
items
? - Kas ir atribūta veids
id
:int
vai tas ir,str
, vai varbÅ«t kÄds pielÄgots veids? - Vai Å”im argumentam vajadzÄtu bÅ«t sarakstam? Vai tajÄ ir iespÄjams nodot korteÄu?
Ja skatÄties uz tÄlÄk norÄdÄ«to tipa anotÄto koda fragmentu un mÄÄ£inÄt atbildÄt uz Å”Ädiem jautÄjumiem, izrÄdÄs, ka tas ir vienkÄrÅ”s uzdevums:
class Resource:
id: bytes
...
def read_metadata(self,
items: Sequence[str]) -> Dict[str, MetadataItem]:
...
read_metadata
neatgriežasNone
jo atgrieÅ”anÄs veids navOptional[ā¦]
.- Arguments
items
ir lÄ«niju secÄ«ba. To nevar atkÄrtot jebkurÄ secÄ«bÄ. - AtribÅ«ts
id
ir baitu virkne.
IdeÄlÄ pasaulÄ varÄtu sagaidÄ«t, ka visi Å”Ädi smalkumi bÅ«tu aprakstÄ«ti iebÅ«vÄtajÄ dokumentÄcijÄ (docstring). TaÄu pieredze sniedz daudz piemÄru, ka kodÄ, ar kuru jÄstrÄdÄ, Å”Äda dokumentÄcija bieži netiek ievÄrota. Pat ja Å”Äda dokumentÄcija ir kodÄ, jÅ«s nevarat paļauties uz tÄs absolÅ«to pareizÄ«bu. Å Ä« dokumentÄcija var bÅ«t neskaidra, neprecÄ«za un iespÄjama pÄrpratumiem. LielÄs komandÄs vai lielos projektos Ŕī problÄma var kļūt ÄrkÄrtÄ«gi aktuÄla.
Lai gan Python ir izcils agrÄ«nÄ vai vidÄjÄ posma projektos, kÄdÄ brÄ«dÄ« veiksmÄ«gi projekti un uzÅÄmumi, kas izmanto Python, var saskarties ar bÅ«tisku jautÄjumu: "Vai mums viss ir jÄpÄrraksta statiski drukÄtÄ valodÄ?"
Tipa pÄrbaudes sistÄmas, piemÄram, mypy, atrisina iepriekÅ” minÄto problÄmu, nodroÅ”inot izstrÄdÄtÄjam formÄlu valodu tipu aprakstÄ«Å”anai un pÄrbaudot, vai tipa deklarÄcijas atbilst programmas ievieÅ”anai (un, pÄc izvÄles, pÄrbaudot to esamÄ«bu). KopumÄ mÄs varam teikt, ka Ŕīs sistÄmas sniedz mums kaut ko lÄ«dzÄ«gu rÅ«pÄ«gi pÄrbaudÄ«tai dokumentÄcijai.
Å Ädu sistÄmu izmantoÅ”anai ir arÄ« citas priekÅ”rocÄ«bas, un tÄs ir pilnÄ«gi nenozÄ«mÄ«gas:
- Tipa pÄrbaudes sistÄma var atklÄt dažas nelielas (un arÄ« ne tik nelielas) kļūdas. Tipisks piemÄrs ir gadÄ«jumi, kad viÅi aizmirst apstrÄdÄt vÄrtÄ«bu
None
vai kÄds cits Ä«paÅ”s nosacÄ«jums. - PÄrveidoÅ”anas kods ir ievÄrojami vienkÄrÅ”ots, jo tipa pÄrbaudÄ«tÄjs bieži vien precÄ«zi norÄda, kÄds kods ir jÄmaina. TajÄ paÅ”Ä laikÄ mums nav jÄpaļaujas uz 100% koda pÄrbaudes pÄrklÄjumu, kas parasti jebkurÄ gadÄ«jumÄ nav iespÄjams. Mums nav jÄiedziļinÄs steka izsekoÅ”anas pÄrskatos, lai noskaidrotu, kas ir nepareizi.
- Pat lielos projektos mypy bieži vien var veikt pilnÄ«gu tipa pÄrbaudi sekundes daļÄ. Un testu izpilde parasti aizÅem desmitiem sekunžu vai pat minÅ«Å”u. Tipa pÄrbaudes sistÄma programmÄtÄjam sniedz tÅ«lÄ«tÄju atgriezenisko saiti un ļauj ÄtrÄk paveikt savu darbu. ViÅam vairs nav jÄraksta trausli un grÅ«ti uzturÄjami vienÄ«bu testi, kas reÄlas entÄ«tijas aizstÄj ar viltojumiem un ielÄpiem, lai tikai iegÅ«tu ÄtrÄkus koda pÄrbaudes rezultÄtus.
IDE un redaktori, piemÄram, PyCharm vai Visual Studio Code, izmanto tipa anotÄcijas, lai izstrÄdÄtÄjiem nodroÅ”inÄtu automÄtisku koda pabeigÅ”anu, kļūdu izcelÅ”anu un atbalstu bieži lietotÄm valodas konstrukcijÄm. Un Ŕīs ir tikai dažas no priekÅ”rocÄ«bÄm, ko sniedz tipizÄcija. Dažiem programmÄtÄjiem tas viss ir galvenais arguments par labu rakstÄ«Å”anai. Tas ir kaut kas tÄds, kas dod labumu tÅ«lÄ«t pÄc ievieÅ”anas. Å im tipu lietoÅ”anas gadÄ«jumam nav nepiecieÅ”ama atseviŔķa tipa pÄrbaudes sistÄma, piemÄram, mypy, lai gan jÄÅem vÄrÄ, ka mypy palÄ«dz uzturÄt konsekvenci starp tipa anotÄcijÄm un kodu.
Mypy fons
Neparastais stÄsts sÄkÄs ApvienotajÄ KaralistÄ, KembridžÄ, dažus gadus pirms pievienoÅ”anÄs Dropbox. Promocijas darba ietvaros es strÄdÄju pie jautÄjuma par statiski tipizÄtu un dinamisku valodu apvienoÅ”anu. Mani iedvesmoja Džeremija SÄ«ka un Valida Tah raksts par pakÄpenisku rakstÄ«Å”anu, kÄ arÄ« projekts Typed Racket. Es mÄÄ£inÄju atrast veidus, kÄ izmantot vienu un to paÅ”u programmÄÅ”anas valodu dažÄdiem projektiem - no maziem skriptiem lÄ«dz kodu bÄzÄm, kas sastÄv no daudziem miljoniem lÄ«niju. TajÄ paÅ”Ä laikÄ es gribÄju nodroÅ”inÄt, lai jebkura mÄroga projektÄ man nebÅ«tu jÄieiet pÄrÄk daudz kompromisu. SvarÄ«ga tÄ visa sastÄvdaļa bija ideja pakÄpeniski pÄriet no netipÄta prototipa projekta uz vispusÄ«gi pÄrbaudÄ«tu, statiski drukÄtu gatavo produktu. Å Ä«s idejas mÅ«sdienÄs lielÄkoties tiek uzskatÄ«tas par paÅ”saprotamÄm, taÄu 2010. gadÄ tas bija jautÄjums, kas joprojÄm tika aktÄ«vi pÄtÄ«ts.
Mans sÄkotnÄjais darbs tipa pÄrbaudÄ nebija vÄrsts uz Python. TÄ vietÄ es izmantoju nelielu "mÄjas" valodu
def Fib(n as Int) as Int
if n <= 1
return n
else
return Fib(n - 1) + Fib(n - 2)
end
end
Sava dizaina vienkÄrÅ”otas valodas izmantoÅ”ana ir izplatÄ«ta pieeja zinÄtniskajos pÄtÄ«jumos. Tas tÄ ir ne tikai tÄpÄc, ka tas ļauj Ätri veikt eksperimentus, kÄ arÄ« tÄpÄc, ka to, kas neattiecas uz pÄtÄ«jumu, var viegli ignorÄt. ReÄlÄs dzÄ«ves programmÄÅ”anas valodas mÄdz bÅ«t liela mÄroga parÄdÄ«bas ar sarežģītÄm implementÄcijÄm, kas palÄnina eksperimentÄÅ”anu. TomÄr visi rezultÄti, kas balstÄ«ti uz vienkÄrÅ”otu valodu, ir nedaudz aizdomÄ«gi, jo, iegÅ«stot Å”os rezultÄtus, pÄtnieks, iespÄjams, ir upurÄjis apsvÄrumus, kas ir svarÄ«gi valodu praktiskajam lietojumam.
Mans Alore tipa pÄrbaudÄ«tÄjs izskatÄ«jÄs ļoti daudzsoloÅ”s, taÄu es gribÄju to pÄrbaudÄ«t, eksperimentÄjot ar reÄlu kodu, kas patiesÄ«bÄ nebija rakstÄ«ts Alore. Man par laimi, Alore valoda lielÄ mÄrÄ balstÄ«jÄs uz tÄm paÅ”Äm idejÄm kÄ Python. Bija pietiekami viegli pÄrveidot tipa pÄrbaudÄ«tÄju, lai tas darbotos ar Python sintaksi un semantiku. Tas ļÄva mums mÄÄ£inÄt veikt tipa pÄrbaudi atvÄrtÄ pirmkoda Python kodÄ. Es arÄ« uzrakstÄ«ju transpilatoru, lai pÄrveidotu Alore kodu Python kodÄ, un izmantoju to, lai tulkotu sava tipa pÄrbaudÄ«tÄja kodu. Tagad man bija Python rakstÄ«ta tipa pÄrbaudes sistÄma, kas atbalstÄ«ja Python apakÅ”kopu, dažas Ŕīs valodas variÄcijas! (Noteikti arhitektÅ«ras lÄmumi, kas bija saprÄtÄ«gi Alore, bija slikti piemÄroti Python; tas joprojÄm ir acÄ«mredzams dažÄs mypy kodu bÄzes daļÄs.)
PatiesÄ«bÄ valodu, ko atbalsta mana tipa sistÄma, Å”obrÄ«d nevarÄja saukt par Python: tas bija Python variants dažu Python 3 tipa anotÄcijas sintakses ierobežojumu dÄļ.
Tas izskatÄ«jÄs kÄ Java un Python maisÄ«jums:
int fib(int n):
if n <= 1:
return n
else:
return fib(n - 1) + fib(n - 2)
Viena no manÄm idejÄm tajÄ laikÄ bija izmantot tipa anotÄcijas, lai uzlabotu veiktspÄju, apkopojot Å”o Python versiju C formÄtÄ vai, iespÄjams, JVM baitkodÄ. Es nonÄcu lÄ«dz prototipa kompilatora rakstÄ«Å”anas stadijai, bet atteicos no Ŕīs idejas, jo pati tipa pÄrbaude izskatÄ«jÄs diezgan noderÄ«ga.
Es beidzot prezentÄju savu projektu PyCon 2013 SantaklÄrÄ. Es par to runÄju arÄ« ar Gvido van Rosumu, Pitona labvÄlÄ«go diktatoru uz mūžu. ViÅÅ” pÄrliecinÄja mani atteikties no pielÄgotÄs sintakses un pieturÄties pie standarta Python 3 sintakses. Python 3 atbalsta funkciju anotÄcijas, tÄpÄc manu piemÄru var pÄrrakstÄ«t, kÄ norÄdÄ«ts tÄlÄk, kÄ rezultÄtÄ tiks izveidota parasta Python programma:
def fib(n: int) -> int:
if n <= 1:
return n
else:
return fib(n - 1) + fib(n - 2)
Man bija jÄpieÅem daži kompromisi (vispirms vÄlos norÄdÄ«t, ka tÄpÄc es izgudroju savu sintaksi). Jo Ä«paÅ”i Python 3.3, tajÄ laikÄ jaunÄkÄ valodas versija, neatbalstÄ«ja mainÄ«gÄs anotÄcijas. Ar Gvido pa e-pastu apspriedu dažÄdas sintaktiskÄs iespÄjas Å”ÄdÄm anotÄcijÄm. MÄs nolÄmÄm mainÄ«gajiem izmantot tipa komentÄrus. Tas sasniedza mÄrÄ·i, taÄu izskatÄ«jÄs nedaudz apgrÅ«tinoÅ”i (Python 3.6 deva mums jaukÄku sintaksi):
products = [] # type: List[str] # Eww
Rakstu komentÄri ir noderÄ«gi arÄ« Python 2 atbalstam, kuram nav iebÅ«vÄta veida anotÄciju atbalsta:
f fib(n):
# type: (int) -> int
if n <= 1:
return n
else:
return fib(n - 1) + fib(n - 2)
IzrÄdÄ«jÄs, ka Å”iem (un citiem) kompromisiem Ä«sti nebija nozÄ«mes ā statiskÄs rakstÄ«Å”anas priekÅ”rocÄ«bas nozÄ«mÄja, ka lietotÄji drÄ«z vien aizmirsa par ne tik perfekto sintaksi. TÄ kÄ Python kods, kas kontrolÄja tipus, vairs neizmantoja Ä«paÅ”u sintaksi, esoÅ”ie Python rÄ«ki un koda procesi turpinÄja darboties normÄli, padarot izstrÄdÄtÄjiem daudz vieglÄk apgÅ«t jauno rÄ«ku.
Gvido arÄ« pÄrliecinÄja mani pievienoties Dropbox pÄc tam, kad pabeidzu savu vecÄko darbu. Å eit sÄkas visinteresantÄkÄ lieta mypy vÄsturÄ.
Lai varÄtu turpinÄt ...
CienÄ«jamie lasÄ«tÄji! Ja izmantojat Python, lÅ«dzu, pastÄstiet mums par projektu apjomu, ko izstrÄdÄjat Å”ajÄ valodÄ.
Avots: www.habr.com