Leiðin til að slá inn 4 milljón línur af Python kóða. 1. hluti

Í dag vekjum við athygli þína á fyrsta hluta þýðingarinnar á efninu um hvernig Dropbox tekur á tegundarstýringu á Python kóða.

Leiðin til að slá inn 4 milljón línur af Python kóða. 1. hluti

Dropbox skrifar mikið í Python. Það er tungumál sem við notum mjög mikið, bæði fyrir bakþjónustu og skrifborðsbiðlaraforrit. Við notum líka Go, TypeScript og Rust mikið, en Python er aðaltungumálið okkar. Miðað við umfang okkar, og við erum að tala um milljónir lína af Python kóða, kom í ljós að kraftmikil vélritun slíks kóða flækti skilning hans að óþörfu og fór að hafa alvarleg áhrif á framleiðni vinnuafls. Til að draga úr þessu vandamáli höfum við byrjað að færa kóðann okkar smám saman yfir í kyrrstæða tegundathugun með mypy. Þetta er líklega vinsælasta sjálfstæða gerð eftirlitskerfið fyrir Python. Mypy er opinn uppspretta verkefni, helstu verktaki þess vinna í Dropbox.

Dropbox var eitt af fyrstu fyrirtækjunum til að innleiða kyrrstæða tegundathugun í Python kóða á þessum mælikvarða. Mypy er notað í þúsundum verkefna þessa dagana. Þetta tól ótal sinnum, eins og þeir segja, "prófað í bardaga." Við erum komin langt með að komast þangað sem við erum núna. Á leiðinni voru margar misheppnaðar framkvæmdir og misheppnaðar tilraunir. Þessi færsla fjallar um sögu kyrrstæðrar tegundaskoðunar í Python, frá grýttri byrjun hennar sem hluti af rannsóknarverkefninu mínu, til dagsins í dag, þegar tegundathugun og tegundavísbending eru orðin algeng fyrir ótal forritara sem skrifa í Python. Þessar aðferðir eru nú studdar af mörgum verkfærum eins og IDE og kóðagreiningartækjum.

Lestu seinni hlutann

Hvers vegna er tegundaskoðun nauðsynleg?

Ef þú hefur einhvern tíma notað kvikt innslátt Python gætirðu ruglast á því hvers vegna það hefur verið svona læti í kringum fasta vélritun og mypy undanfarið. Eða kannski líkar þér við Python einmitt vegna kraftmikillar vélritunar og það sem er að gerast kemur þér einfaldlega í uppnám. Lykillinn að gildi kyrrstættrar vélritunar er umfang lausnanna: því stærra verkefnið þitt, því meira hallast þú að kyrrstöðu vélritun, og á endanum, því meira þarftu það í raun.

Segjum sem svo að ákveðið verkefni hafi náð stærðinni tugþúsundir línur og í ljós hafi komið að nokkrir forritarar eru að vinna að því. Þegar við skoðum svipað verkefni, byggt á reynslu okkar, getum við sagt að skilningur á kóða þess sé lykillinn að því að halda þróunaraðilum afkastamiklum. Án tegundaskýringa getur verið erfitt að átta sig á, til dæmis hvaða rök á að senda til falls, eða hvaða tegund fall getur skilað. Hér eru dæmigerðar spurningar sem oft er erfitt að svara án þess að nota textaskýringar:

  • Getur þessi aðgerð skilað sér None?
  • Hver skyldu þessi rök vera? items?
  • Hver er eigindategundin id: int er það, str, eða kannski einhver sérsniðin tegund?
  • Ætti þessi rök að vera listi? Er hægt að gefa tuple í það?

Ef þú skoðar eftirfarandi tegundarmerkta kóðabút og reynir að svara svipuðum spurningum, kemur í ljós að þetta er einfaldasta verkefnið:

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

  • read_metadata skilar sér ekki None, þar sem skilategundin er það ekki Optional[…].
  • Rök items er röð af línum. Það er ekki hægt að endurtaka það af handahófi.
  • Eiginleiki id er strengur af bætum.

Í hugsjónaheimi mætti ​​búast við því að öllum slíkum fíngerðum væri lýst í innbyggðu skjölunum (docstring). En reynslan gefur mörg dæmi um þá staðreynd að slík skjöl eru oft ekki fylgst með í kóðanum sem þú þarft að vinna með. Jafnvel þó að slík skjöl séu til staðar í kóðanum er ekki hægt að treysta á algjöran réttmæti hans. Þessi skjöl geta verið óljós, ónákvæm og opin fyrir misskilningi. Í stórum teymum eða stórum verkefnum getur þetta vandamál orðið mjög bráð.

Þó að Python skari framúr á fyrstu eða millistigum verkefna, gætu á einhverjum tímapunkti vel heppnuð verkefni og fyrirtæki sem nota Python staðið frammi fyrir þeirri mikilvægu spurningu: „Eigum við að endurskrifa allt á kyrrstætt vélritað tungumál?“.

Tegundarprófunarkerfi eins og mypy leysa vandamálið hér að ofan með því að útvega forritaranum formlegt tungumál til að lýsa tegundum og með því að athuga hvort tegundayfirlýsingarnar passi við framkvæmd forritsins (og, valfrjálst, athuga hvort þær séu til). Almennt má segja að þessi kerfi hafi til ráðstöfunar eitthvað eins og vandlega yfirfarin skjöl.

Notkun slíkra kerfa hefur aðra kosti og þeir eru nú þegar algjörlega óléttir:

  • Gerðareftirlitskerfið getur greint nokkrar litlar (og ekki svo litlar) villur. Dæmigerð dæmi er þegar þeir gleyma að vinna úr gildi None eða einhver önnur sérstök skilyrði.
  • Endurnýjun kóða er einfölduð til muna vegna þess að tegundaeftirlitskerfið er oft mjög nákvæmt um hvaða kóða þarf að breyta. Á sama tíma þurfum við ekki að vonast eftir 100% kóðaþekju með prófunum, sem í öllum tilvikum er yfirleitt ekki framkvæmanlegt. Við þurfum ekki að kafa ofan í dýpt staflasporsins til að komast að orsök vandans.
  • Jafnvel í stórum verkefnum getur mypy oft gert fullgerðaskoðun á sekúndubroti. Og framkvæmd prófa tekur venjulega tugi sekúndna eða jafnvel mínútur. Tegundarprófunarkerfið gefur forritaranum tafarlausa endurgjöf og gerir honum kleift að vinna vinnuna sína hraðar. Hann þarf ekki lengur að skrifa brothætt og erfitt að viðhalda einingaprófum sem koma í stað raunverulegra eininga fyrir spotta og plástra bara til að fá niðurstöður kóðaprófa hraðar.

IDE og ritstjórar eins og PyCharm eða Visual Studio Code nota kraft tegundaskýringa til að veita forriturum frágang kóða, auðkenningu á villum og stuðning við algengar tungumálasmíðar. Og þetta eru bara nokkrir af kostunum við að slá inn. Fyrir suma forritara er þetta allt aðalröksemdin fyrir vélritun. Þetta er eitthvað sem hagnast strax eftir innleiðingu. Þetta notkunartilvik fyrir gerðir krefst ekki sérstaks tegundaeftirlitskerfis eins og mypy, þó að það skal tekið fram að mypy hjálpar til við að halda tegundaskýringum í samræmi við kóða.

Bakgrunnur mypy

Saga mypy hófst í Bretlandi, í Cambridge, nokkrum árum áður en ég gekk til liðs við Dropbox. Ég hef tekið þátt, sem hluti af doktorsrannsókn minni, í sameiningu kyrrstætt vélritaðra og kraftmikilla tungumála. Ég var innblásin af grein um stigvaxandi vélritun eftir Jeremy Siek og Walid Taha og af Typed Racket verkefninu. Ég reyndi að finna leiðir til að nota sama forritunarmálið fyrir ýmis verkefni - allt frá litlum skriftum til kóðagrunna sem samanstanda af mörgum milljónum lína. Jafnframt vildi ég tryggja að í verkefni af hvaða stærðargráðu sem er þyrftu menn ekki að gera of stórar málamiðlanir. Mikilvægur hluti af þessu öllu var hugmyndin um að færa sig smám saman frá ógerðu frumgerð verkefni yfir í alhliða prófuð kyrrstætt vélrituð fullunnin vöru. Þessar hugmyndir eru að mestu leyti sjálfsagðar þessa dagana, en árið 2010 var það vandamál sem enn var verið að kanna með virkum hætti.

Upprunalega verk mitt við tegundaskoðun var ekki beint að Python. Í staðinn notaði ég lítið "heimatilbúið" tungumál Alor. Hér er dæmi sem gerir þér kleift að skilja hvað við erum að tala um (tegundarskýringar eru valfrjálsar hér):

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

Notkun einfaldaðs móðurmáls er algeng nálgun sem notuð er í vísindarannsóknum. Þetta er svo, ekki síst vegna þess að það gerir þér kleift að gera tilraunir fljótt, og einnig vegna þess að það sem hefur ekkert með rannsóknir að gera er auðvelt að hunsa. Raunveruleg forritunarmál hafa tilhneigingu til að vera stórfyrirbæri með flóknum útfærslum og það hægir á tilraunum. Hins vegar virðast allar niðurstöður byggðar á einfölduðu tungumáli svolítið tortryggilegar, þar sem rannsakandinn kann að hafa fórnað mikilvægum sjónarmiðum við hagnýta notkun tungumála við að fá þessar niðurstöður.

Tegundafgreiðslumaðurinn minn fyrir Alore leit mjög efnilegur út, en mig langaði að prófa hann með því að gera tilraunir með alvöru kóða, sem þú gætir sagt, var ekki skrifaður í Alore. Sem betur fer fyrir mig var Alore tungumálið að mestu byggt á sömu hugmyndum og Python. Það var nógu auðvelt að breyta tegundaskoðuninni þannig að hann gæti unnið með setningafræði Python og merkingarfræði. Þetta gerði okkur kleift að prófa að slá inn opinn uppspretta Python kóða. Að auki skrifaði ég transpiler til að umbreyta kóða sem skrifaður er í Alore í Python kóða og notaði hann til að þýða typechecker kóðann minn. Nú var ég með tegundaskoðunarkerfi skrifað í Python sem styður undirmengi af Python, einhvers konar því tungumáli! (Ákveðnar byggingarákvarðanir sem voru skynsamlegar fyrir Alore henta illa fyrir Python og þetta er enn áberandi í hluta mypy kóðagrunnsins.)

Reyndar gat tungumálið sem tegundarkerfið mitt styður ekki alveg verið kallað Python á þessum tímapunkti: það var afbrigði af Python vegna takmarkana á Python 3 tegundarskýringarsetningafræðinni.

Það leit út eins og blanda af Java og Python:

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

Ein af hugmyndum mínum á þeim tíma var að nota tegundaskýringar til að bæta árangur með því að setja saman þessa tegund af Python í C, eða kannski JVM bækakóða. Ég komst á það stig að skrifa frumgerð þýðanda, en ég hætti við þessa hugmynd, þar sem tegundaskoðunin sjálf leit mjög gagnleg út.

Ég endaði á að kynna verkefnið mitt á PyCon 2013 í Santa Clara. Ég talaði líka um þetta við Guido van Rossum, hinn velviljaða Python einræðisherra fyrir lífstíð. Hann sannfærði mig um að sleppa eigin setningafræði og halda mig við hefðbundna Python 3. Python 3 styður aðgerðaskýringar, svo dæmið mitt gæti verið endurskrifað eins og sýnt er hér að neðan, sem leiðir til venjulegs Python forrits:

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

Ég þurfti að gera nokkrar málamiðlanir (fyrst af öllu vil ég taka fram að ég fann upp mína eigin setningafræði einmitt af þessari ástæðu). Sérstaklega studdi Python 3.3, nýjasta útgáfan af tungumálinu á þeim tíma, ekki breytuskýringar. Ég ræddi við Guido í tölvupósti um ýmsa möguleika á setningafræðilegri hönnun á slíkum athugasemdum. Við ákváðum að nota tegund athugasemda fyrir breytur. Þetta þjónaði tilætluðum tilgangi, en var nokkuð fyrirferðarmikið (Python 3.6 gaf okkur flottari setningafræði):

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

Tegundar athugasemdir komu einnig að góðum notum til að styðja Python 2, sem hefur ekki innbyggðan stuðning fyrir tegundaskýringar:

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

Það kom í ljós að þessi (og önnur) málamiðlun skipti engu máli - ávinningurinn af kyrrstöðu vélritun gerði það að verkum að notendur gleymdu fljótlega minna en fullkominni setningafræði. Þar sem engar sérstakar setningafræðilegar smíðar voru notaðar í tegundaskoðaða Python kóðanum, héldu núverandi Python verkfæri og kóðavinnsluferli áfram að virka eðlilega, sem gerði það mun auðveldara fyrir forritara að læra á nýja tólið.

Guido sannfærði mig líka um að ganga til liðs við Dropbox eftir að ég kláraði útskriftarritgerðina. Þetta er þar sem áhugaverðasti hluti mypy sögunnar hefst.

Til að halda áfram ...

Kæru lesendur! Ef þú notar Python, vinsamlegast segðu okkur frá umfangi verkefna sem þú þróar á þessu tungumáli.

Leiðin til að slá inn 4 milljón línur af Python kóða. 1. hluti
Leiðin til að slá inn 4 milljón línur af Python kóða. 1. hluti

Heimild: www.habr.com

Bæta við athugasemd