It-triq għall-iċċekkjar tat-tip 4 miljun linja ta 'kodiċi Python. Parti 1

Illum inġibu għall-attenzjoni tiegħek l-ewwel parti tat-traduzzjoni tal-materjal dwar kif Dropbox jittratta l-kontroll tat-tip tal-kodiċi Python.

It-triq għall-iċċekkjar tat-tip 4 miljun linja ta 'kodiċi Python. Parti 1

Dropbox jikteb ħafna f'Python. Hija lingwa li nużaw b'mod wiesa' ħafna, kemm għas-servizzi back-end kif ukoll għall-applikazzjonijiet tal-klijenti tad-desktop. Aħna nużaw ukoll Go, TypeScript u Rust ħafna, iżda Python huwa l-lingwa ewlenija tagħna. Meta wieħed iqis l-iskala tagħna, u qed nitkellmu dwar miljuni ta 'linji ta' kodiċi Python, irriżulta li l-ittajpjar dinamiku ta 'tali kodiċi kkumplikat bla bżonn il-fehim tiegħu u beda jaffettwa serjament il-produttività tax-xogħol. Biex tittaffa din il-problema, bdejna gradwalment transizzjoni tal-kodiċi tagħna għall-iċċekkjar tat-tip statiku bl-użu ta 'mypy. Din hija probabbilment l-aktar sistema ta 'verifika tat-tip waħedha popolari għal Python. Mypy huwa proġett ta 'sors miftuħ, l-iżviluppaturi ewlenin tiegħu jaħdmu fi Dropbox.

Dropbox kienet waħda mill-ewwel kumpaniji li implimentat verifika tat-tip statiku fil-kodiċi Python fuq din l-iskala. Mypy jintuża f'eluf ta' proġetti f'dawn il-jiem. Din l-għodda għadd ta 'drabi, kif jgħidu, "ittestjat fil-battalja." Imxejna triq twila biex naslu fejn qegħdin issa. Tul it-triq, kien hemm ħafna impriżi li ma rnexxewx u esperimenti falluti. Din il-kariga tkopri l-istorja tal-iċċekkjar tat-tip statiku f'Python, mill-bidu tal-blat tagħha bħala parti mill-proġett ta 'riċerka tiegħi, sal-lum, meta l-iċċekkjar tat-tip u l-ħjiel tat-tip saru komuni għal għadd ta' żviluppaturi li jiktbu f'Python. Dawn il-mekkaniżmi issa huma appoġġjati minn ħafna għodod bħal IDEs u analizzaturi tal-kodiċi.

Aqra t-tieni parti

Għaliex hija meħtieġa l-iċċekkjar tat-tip?

Jekk qatt użajt Python ittajpjat b'mod dinamiku, jista 'jkollok xi konfużjoni dwar għaliex dan l-aħħar kien hemm tali fuss madwar ittajpjar statiku u mypy. Jew forsi inti tixtieq Python preċiżament minħabba l-ittajpjar dinamiku tiegħu, u dak li qed jiġri sempliċement idejk. Iċ-ċavetta għall-valur tat-tajpjar statiku hija l-iskala tas-soluzzjonijiet: iktar ma jkun kbir il-proġett tiegħek, aktar tkun iddejjaq lejn ittajpjar statiku, u fl-aħħar, aktar ikollok bżonnha tassew.

Ejja ngħidu li ċertu proġett laħaq id-daqs ta 'għexieren ta' eluf ta 'linji, u rriżulta li diversi programmaturi qed jaħdmu fuqu. Meta nħarsu lejn proġett simili, ibbażat fuq l-esperjenza tagħna, nistgħu ngħidu li l-fehim tal-kodiċi tiegħu se jkun iċ-ċavetta biex l-iżviluppaturi jinżammu produttivi. Mingħajr annotazzjonijiet tat-tip, jista 'jkun diffiċli biex insemmu, pereżempju, liema argumenti jgħaddu lil funzjoni, jew liema tipi funzjoni tista' tirritorna. Hawn huma mistoqsijiet tipiċi li ħafna drabi huma diffiċli biex twieġeb mingħajr ma tuża annotazzjonijiet tat-tip:

  • Tista' tirritorna din il-funzjoni None?
  • X'għandu jkun dan l-argument? items?
  • X'inhu t-tip ta' attribut id: int hu, str, jew forsi xi tip tad-dwana?
  • Dan l-argument għandu jkun lista? Huwa possibbli li tgħaddi tuple lilha?

Jekk tħares lejn is-snippet tal-kodiċi annotat tat-tip li ġej u tipprova twieġeb mistoqsijiet simili, jirriżulta li dan huwa l-aktar kompitu sempliċi:

class Resource:
    id: bytes
    ...
    def read_metadata(self, 
                      items: Sequence[str]) -> Dict[str, MetadataItem]:
        ...

  • read_metadata ma jerġax lura None, peress li t-tip ta 'ritorn mhuwiex Optional[…].
  • argument items hija sekwenza ta' linji. Ma jistax jiġi ripetut bl-addoċċ.
  • Attribut id hija sensiela ta' bytes.

F'dinja ideali, wieħed jistenna li dawn ir-rqaq kollha jkunu deskritti fid-dokumentazzjoni integrata (docstring). Iżda l-esperjenza tagħti ħafna eżempji tal-fatt li tali dokumentazzjoni ħafna drabi ma tiġix osservata fil-kodiċi li miegħu trid taħdem. Anke jekk tali dokumentazzjoni tkun preżenti fil-kodiċi, wieħed ma jistax joqgħod fuq il-korrettezza assoluta tagħha. Din id-dokumentazzjoni tista’ tkun vaga, mhux preċiża, u miftuħa għal nuqqas ta’ ftehim. F'timijiet kbar jew proġetti kbar, din il-problema tista 'ssir estremament akuta.

Filwaqt li Python jeċċella fl-istadji bikrija jew intermedji tal-proġetti, f'xi punt proġetti ta 'suċċess u kumpaniji li jużaw Python jistgħu jiffaċċjaw il-mistoqsija vitali: "Għandna nerġgħu niktbu kollox b'lingwa ttajpjata b'mod statiku?".

Sistemi ta' verifika tat-tip bħal mypy isolvu l-problema ta' hawn fuq billi jipprovdu lill-iżviluppatur b'lingwa formali għad-deskrizzjoni tat-tipi, u billi jiċċekkjaw li d-dikjarazzjonijiet tat-tip jaqblu mal-implimentazzjoni tal-programm (u, b'mod fakultattiv, billi jiċċekkjaw l-eżistenza tagħhom). B'mod ġenerali, nistgħu ngħidu li dawn is-sistemi jpoġġu għad-dispożizzjoni tagħna xi ħaġa bħal dokumentazzjoni kkontrollata bir-reqqa.

L-użu ta 'sistemi bħal dawn għandu vantaġġi oħra, u huma diġà kompletament mhux trivjali:

  • Is-sistema ta 'kontroll tat-tip tista' tiskopri xi żbalji żgħar (u mhux daqshekk żgħar). Eżempju tipiku huwa meta jinsew jipproċessaw valur None jew xi kundizzjoni speċjali oħra.
  • Ir-refactoring tal-kodiċi huwa ssimplifikat ħafna minħabba li s-sistema tal-iċċekkjar tat-tip ħafna drabi hija preċiża ħafna dwar liema kodiċi jeħtieġ li jinbidel. Fl-istess ħin, m'għandniex bżonn nittamaw għal kopertura tal-kodiċi 100% bit-testijiet, li, fi kwalunkwe każ, normalment ma jkunx fattibbli. M'għandniex bżonn nidħlu fil-fond tat-traċċa tal-munzell biex issir taf il-kawża tal-problema.
  • Anke fuq proġetti kbar, mypy spiss jista 'jagħmel verifika sħiħa tat-tip fi frazzjoni ta' sekonda. U l-eżekuzzjoni tat-testijiet normalment tieħu għexieren ta 'sekondi jew saħansitra minuti. Is-sistema ta 'kontroll tat-tip tagħti lill-programmatur feedback immedjat u tippermettilu jagħmel xogħolu aktar malajr. M'għadux jeħtieġ li jikteb fraġli u diffiċli biex iżomm testijiet ta 'unità li jissostitwixxu entitajiet reali b'mocks u garżi biss biex jiksbu riżultati tat-test tal-kodiċi aktar malajr.

IDEs u edituri bħal PyCharm jew Visual Studio Code jużaw il-qawwa tal-annotazzjonijiet tat-tip biex jipprovdu lill-iżviluppaturi bit-tlestija tal-kodiċi, l-enfasi tal-iżbalji, u l-appoġġ għal kostruzzjonijiet tal-lingwa użati b'mod komuni. U dawn huma biss ftit mill-benefiċċji tat-tajpjar. Għal xi programmaturi, dan kollu huwa l-argument ewlieni favur it-tajpjar. Din hija xi ħaġa li tibbenefika immedjatament wara l-implimentazzjoni. Dan il-każ ta 'użu għat-tipi ma jeħtieġx sistema separata ta' verifika tat-tip bħal mypy, għalkemm għandu jiġi nnutat li mypy jgħin biex l-annotazzjonijiet tat-tip jinżammu konsistenti mal-kodiċi.

Sfond ta' mypy

L-istorja ta' mypy bdiet fir-Renju Unit, f'Cambridge, ftit snin qabel ma ngħaqadt ma' Dropbox. Jien kont involut, bħala parti mir-riċerka tad-dottorat tiegħi, fl-unifikazzjoni ta' lingwi statikament ittajpjati u dinamiċi. Ġejt ispirat minn artiklu dwar ittajpjar inkrementali minn Jeremy Siek u Walid Taha, u mill-proġett Typed Racket. Ippruvajt insib modi kif nuża l-istess lingwa ta 'programmar għal diversi proġetti - minn skripts żgħar għal bażijiet ta' kodiċi li jikkonsistu f'ħafna miljuni ta 'linji. Fl-istess ħin, ridt nassigura li fi proġett ta’ kull skala, wieħed ma jkollux għalfejn jagħmel kompromessi kbar wisq. Parti importanti minn dan kollu kienet l-idea li gradwalment nimxu minn proġett prototip mhux ittajpjat għal prodott lest ittajpjat b'mod statiku ttestjat b'mod komprensiv. Dawn il-ġranet, dawn l-ideat huma fil-biċċa l-kbira meħuda for granted, iżda fl-2010 kienet problema li kienet għadha qed tiġi esplorata b'mod attiv.

Ix-xogħol oriġinali tiegħi fil-verifika tat-tip ma kienx immirat lejn Python. Minflok, użajt lingwa żgħira "magħmula mid-dar". Alore. Hawn hu eżempju li se jħallik tifhem dak li qed nitkellmu (l-annotazzjonijiet tat-tip huma fakultattivi hawn):

def Fib(n as Int) as Int
  if n <= 1
    return n
  else
    return Fib(n - 1) + Fib(n - 2)
  end
end

L-użu ta' lingwa nattiva simplifikata huwa approċċ komuni użat fir-riċerka xjentifika. Dan huwa hekk, mhux l-inqas għax jippermettilek li twettaq esperimenti malajr, u wkoll minħabba l-fatt li dak li m'għandu x'jaqsam xejn ma 'l-istudju jista' jiġi injorat faċilment. Il-lingwi tal-ipprogrammar tad-dinja reali għandhom it-tendenza li jkunu fenomeni fuq skala kbira b'implimentazzjonijiet kumplessi, u dan inaqqas l-esperimentazzjoni. Madankollu, kwalunkwe riżultat ibbażat fuq lingwa simplifikata jidher xi ftit suspettuż, peress li fil-kisba ta 'dawn ir-riżultati r-riċerkatur jista' jkun sagrifikat kunsiderazzjonijiet importanti għall-użu prattiku tal-lingwi.

Il-kontrollur tat-tip tiegħi għal Alore deher promettenti ħafna, imma ridt nittestjah billi nesperimenta b'kodiċi reali, li, tista 'tgħid, ma kienx miktub f'Alore. Fortunatament għalija, il-lingwa Alore kienet fil-biċċa l-kbira bbażata fuq l-istess ideat bħal Python. Kien faċli biżżejjed li terġa 'tinkiseb it-typechecker sabiex ikun jista' jaħdem bis-sintassi u s-semantika ta 'Python. Dan ippermetta li nippruvaw niċċekkjaw it-tip fil-kodiċi Python open source. Barra minn hekk, ktibt transpiler biex tikkonverti kodiċi miktub f'Alore għal kodiċi Python u użajt biex tittraduċi l-kodiċi tat-typechecker tiegħi. Issa kelli sistema ta 'kontroll tat-tip miktuba f'Python li appoġġjat subsett ta' Python, xi tip ta 'dik il-lingwa! (Ċerti deċiżjonijiet arkitettoniċi li għamlu sens għal Alore ma tantx kienu adattati għal Python, u dan għadu notevoli f'partijiet tal-codebase mypy.)

Fil-fatt, il-lingwa appoġġjata mis-sistema tat-tip tiegħi ma setgħetx tissejjaħ Python f'dan il-punt: kienet varjant ta 'Python minħabba xi limitazzjonijiet tas-sintassi tal-annotazzjoni tat-tip Python 3.

Deher qisu taħlita ta' Java u Python:

int fib(int n):
    if n <= 1:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

Waħda mill-ideat tiegħi dak iż-żmien kienet li nuża annotazzjonijiet tat-tip biex ittejjeb il-prestazzjoni billi niġbor dan it-tip ta 'Python għal C, jew forsi JVM bytecode. Wasalt fl-istadju tal-kitba ta 'prototip ta' kompilatur, imma abbandunajt din l-idea, peress li l-iċċekkjar tat-tip innifsu deher pjuttost utli.

Spiċċajt nippreżenta l-proġett tiegħi fil-PyCon 2013 f'Santa Klara. Dwar dan tkellimt ukoll ma’ Guido van Rossum, id-dittatur benevolenti ta’ Python għall-ħajja. Huwa kkonvinċini biex inneħħi s-sintassi tiegħi stess u nżomm mas-sintassi standard ta 'Python 3. Python 3 jappoġġja annotazzjonijiet tal-funzjonijiet, għalhekk l-eżempju tiegħi jista' jinkiteb mill-ġdid kif muri hawn taħt, li jirriżulta fi programm Python normali:

def fib(n: int) -> int:
    if n <= 1:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

Kelli nagħmel xi kompromessi (l-ewwel nett, irrid ninnota li ivvintajt is-sintassi tiegħi stess għal din ir-raġuni). B'mod partikolari, Python 3.3, l-aktar verżjoni reċenti tal-lingwa f'dak iż-żmien, ma appoġġjatx annotazzjonijiet varjabbli. Iddiskutejt ma' Guido permezz ta' e-mail diversi possibbiltajiet għal disinn sintattiku ta' annotazzjonijiet bħal dawn. Iddeċidejna li nużaw kummenti tat-tip għall-varjabbli. Dan serva l-iskop maħsub, iżda kien kemmxejn ingombranti (Python 3.6 tana sintassi aħjar):

products = []  # type: List[str]  # Eww

Il-kummenti tat-tip kienu wkoll utli biex jappoġġjaw Python 2, li m'għandux appoġġ inkorporat għall-annotazzjonijiet tat-tip:

f fib(n):
    # type: (int) -> int
    if n <= 1:
        return n
    else:
        return fib(n - 1) + fib(n - 2)

Irriżulta li dawn il-kompromessi (u oħrajn) ma tantx kienu importanti - il-benefiċċji tat-tajpjar statiku fisser li l-utenti malajr insew is-sintassi inqas minn perfetta. Peress li l-ebda kostruzzjoni sintattika speċjali ma ntużat fil-kodiċi Python ikkontrollat ​​tat-tip, l-għodod eżistenti Python u l-proċessi tal-ipproċessar tal-kodiċi komplew jaħdmu b'mod normali, u għamilha ħafna aktar faċli għall-iżviluppaturi biex jitgħallmu l-għodda l-ġdida.

Guido ikkonvinċini wkoll biex ningħaqad ma' Dropbox wara li lestejt it-teżi tal-gradwati tiegħi. Dan huwa fejn tibda l-aktar parti interessanti tal-istorja mypy.

Biex titkompla ...

Għeżież qarrejja! Jekk tuża Python, jekk jogħġbok għidilna dwar l-iskala ta' proġetti li tiżviluppa f'din il-lingwa.

It-triq għall-iċċekkjar tat-tip 4 miljun linja ta 'kodiċi Python. Parti 1
It-triq għall-iċċekkjar tat-tip 4 miljun linja ta 'kodiċi Python. Parti 1

Sors: www.habr.com

Żid kumment