Njia ya kuangalia mistari milioni 4 ya nambari ya Python. Sehemu 1

Leo tunakuletea sehemu ya kwanza ya tafsiri ya nyenzo kuhusu jinsi Dropbox inavyoshughulika na udhibiti wa aina ya msimbo wa Python.

Njia ya kuangalia mistari milioni 4 ya nambari ya Python. Sehemu 1

Dropbox inaandika mengi katika Python. Ni lugha ambayo tunatumia kwa upana sana, kwa huduma za nyuma na programu za mteja wa eneo-kazi. Pia tunatumia Go, TypeScript na Rust sana, lakini Python ndio lugha yetu kuu. Kwa kuzingatia kiwango chetu, na tunazungumza juu ya mamilioni ya mistari ya msimbo wa Python, iliibuka kuwa uchapaji wa nguvu wa nambari kama hiyo ulichanganya uelewa wake na kuanza kuathiri sana tija ya wafanyikazi. Ili kupunguza tatizo hili, tumeanza kubadilisha hatua kwa hatua msimbo wetu kuwa ukaguzi wa aina tuli kwa kutumia mypy. Labda huu ndio mfumo maarufu zaidi wa kuangalia aina ya Python. Mypy ni mradi wa chanzo wazi, watengenezaji wake wakuu hufanya kazi katika Dropbox.

Dropbox ilikuwa moja ya kampuni za kwanza kutekeleza ukaguzi wa aina tuli katika nambari ya Python kwa kiwango hiki. Mypy inatumika katika maelfu ya miradi siku hizi. Chombo hiki mara nyingi, kama wanasema, "kilichojaribiwa katika vita." Tumetoka mbali sana kufika hapa tulipo sasa. Njiani, kulikuwa na ahadi nyingi ambazo hazikufanikiwa na majaribio yaliyoshindwa. Chapisho hili linashughulikia historia ya ukaguzi wa aina tuli katika Python, kutoka mwanzo wake wa miamba kama sehemu ya mradi wangu wa utafiti, hadi leo, wakati ukaguzi wa aina na uorodheshaji wa aina umekuwa kawaida kwa watengenezaji wengi wanaoandika kwenye Python. Taratibu hizi sasa zinaungwa mkono na zana nyingi kama vile IDE na vichanganuzi misimbo.

β†’ Soma sehemu ya pili

Kwa nini ukaguzi wa aina ni muhimu?

Ikiwa umewahi kutumia Python iliyochapwa kwa nguvu, unaweza kuwa na machafuko juu ya kwa nini kumekuwa na mzozo wa kuchapa tuli na mypy hivi majuzi. Au labda unapenda Python haswa kwa sababu ya uchapaji wake wa nguvu, na kinachotokea kinakukasirisha. Ufunguo wa thamani ya uchapaji tuli ni ukubwa wa suluhu: kadiri mradi wako unavyokuwa mkubwa, ndivyo unavyoegemea zaidi katika uchapaji tuli, na mwishowe, ndivyo unavyohitaji zaidi.

Tuseme mradi fulani umefikia saizi ya makumi ya maelfu ya mistari, na ikawa kwamba watengenezaji wa programu kadhaa wanafanya kazi juu yake. Kuangalia mradi kama huo, kulingana na uzoefu wetu, tunaweza kusema kwamba kuelewa kanuni zake kutakuwa ufunguo wa kuweka watengenezaji wa tija. Bila maelezo ya aina, inaweza kuwa vigumu kubaini, kwa mfano, ni hoja gani za kupitisha kwa chaguo za kukokotoa, au ni aina gani za chaguo za kukokotoa zinaweza kurudi. Hapa kuna maswali ya kawaida ambayo mara nyingi ni ngumu kujibu bila kutumia maelezo ya aina:

  • Je, chaguo hili la kukokotoa linaweza kurudi None?
  • Hoja hii inapaswa kuwa nini? items?
  • Ni aina gani ya sifa id: int ni, str, au labda aina fulani maalum?
  • Je, hoja hii inapaswa kuwa orodha? Je, inawezekana kupitisha tuple kwake?

Ukiangalia kijisehemu kifuatacho cha msimbo uliofafanuliwa na kujaribu kujibu maswali kama hayo, inabadilika kuwa hii ndiyo kazi rahisi zaidi:

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

  • read_metadata hairudi None, kwa kuwa aina ya kurudi sio Optional[…].
  • hoja items ni mlolongo wa mistari. Haiwezi kurudiwa kwa nasibu.
  • Sifa id ni msururu wa ka.

Katika ulimwengu mzuri, mtu angetarajia kwamba hila zote kama hizo zingeelezewa katika hati zilizojengwa ndani (docstring). Lakini uzoefu unatoa mifano mingi ya ukweli kwamba nyaraka hizo mara nyingi hazizingatiwi katika kanuni ambayo unapaswa kufanya kazi nayo. Hata kama nyaraka hizo zipo katika kanuni, mtu hawezi kutegemea usahihi wake kabisa. Hati hizi zinaweza kuwa wazi, zisizo sahihi, na wazi kwa kutoelewana. Katika timu kubwa au miradi mikubwa, shida hii inaweza kuwa kubwa sana.

Wakati Python inafanikiwa katika hatua za mwanzo au za kati za miradi, wakati fulani miradi iliyofanikiwa na kampuni zinazotumia Python zinaweza kukabili swali muhimu: "Je!

Chapa mifumo ya kukagua kama mypy kutatua tatizo hapo juu kwa kumpa msanidi programu lugha rasmi ya kuelezea aina, na kwa kuangalia matamko ya aina hiyo yanalingana na utekelezaji wa programu (na, kwa hiari, kwa kuangalia uwepo wao). Kwa ujumla, tunaweza kusema kwamba mifumo hii inatuwekea kitu kama hati zilizoangaliwa kwa uangalifu.

Matumizi ya mifumo kama hii ina faida zingine, na tayari sio ndogo kabisa:

  • Mfumo wa kuangalia aina unaweza kugundua makosa madogo (na sio madogo sana). Mfano wa kawaida ni wakati wanasahau kuchakata thamani None au hali nyingine maalum.
  • Urekebishaji wa msimbo umerahisishwa sana kwa sababu mfumo wa kukagua aina mara nyingi huwa sahihi sana kuhusu ni msimbo gani unahitaji kubadilishwa. Wakati huo huo, hatuna haja ya kutumaini chanjo ya 100% ya kanuni na vipimo, ambayo, kwa hali yoyote, kwa kawaida haiwezekani. Hatuhitaji kuzama ndani ya kina cha ufuatiliaji wa rafu ili kujua sababu ya tatizo.
  • Hata kwenye miradi mikubwa, mypy mara nyingi inaweza kufanya ukaguzi wa aina kamili kwa sehemu ya sekunde. Na utekelezaji wa vipimo kawaida huchukua makumi ya sekunde au hata dakika. Mfumo wa kuangalia aina hutoa maoni ya papo hapo ya programu na kumruhusu kufanya kazi yake haraka. Hahitaji tena kuandika tete na ngumu ili kudumisha majaribio ya vitengo ambayo hubadilisha huluki halisi kwa kejeli na viraka ili tu kupata matokeo ya majaribio ya msimbo haraka.

Vitambulisho na wahariri kama vile PyCharm au Visual Studio Code hutumia uwezo wa aina ya ufafanuzi ili kuwapa wasanidi programu kukamilisha msimbo, kuangazia makosa, na usaidizi wa miundo ya lugha inayotumiwa sana. Na hizi ni baadhi tu ya faida za kuandika. Kwa watengenezaji programu wengine, hii yote ndio hoja kuu inayopendelea uchapaji. Hili ni jambo ambalo linafaidika mara baada ya utekelezaji. Kesi hii ya utumiaji kwa aina hauitaji mfumo tofauti wa kuangalia kama mypy, ingawa ikumbukwe kuwa mypy husaidia kuweka maelezo ya aina kuendana na nambari.

Asili ya mypy

Historia ya mypy ilianza nchini Uingereza, huko Cambridge, miaka michache kabla ya kujiunga na Dropbox. Nimehusika, kama sehemu ya utafiti wangu wa udaktari, katika uunganishaji wa lugha zilizochapwa kwa takwimu na zinazobadilika. Nilitiwa moyo na makala kuhusu uchapaji wa nyongeza na Jeremy Siek na Walid Taha, na mradi wa Typed Racket. Nilijaribu kutafuta njia za kutumia lugha sawa ya programu kwa miradi mbali mbali - kutoka hati ndogo hadi misingi ya nambari inayojumuisha mamilioni ya mistari. Wakati huo huo, nilitaka kuhakikisha kuwa katika mradi wa kiwango chochote, mtu hatalazimika kufanya maelewano makubwa sana. Sehemu muhimu ya haya yote ilikuwa wazo la kuhama polepole kutoka kwa mradi wa mfano ambao haujachapishwa hadi bidhaa iliyokamilishwa iliyojaribiwa kwa kina. Siku hizi, mawazo haya kwa kiasi kikubwa yanachukuliwa kuwa ya kawaida, lakini mwaka wa 2010 lilikuwa tatizo ambalo lilikuwa bado linachunguzwa kikamilifu.

Kazi yangu ya asili katika kuangalia aina haikulenga Python. Badala yake, nilitumia lugha ndogo "ya nyumbani". Alore. Huu hapa ni mfano ambao utakuruhusu kuelewa tunachozungumza (aina ya maelezo ni ya hiari hapa):

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

Kutumia lugha ya asili iliyorahisishwa ni mbinu ya kawaida inayotumiwa katika utafiti wa kisayansi. Hii ni hivyo, sio kwa sababu inakuwezesha kufanya majaribio haraka, na pia kutokana na ukweli kwamba kile ambacho hakihusiani na utafiti kinaweza kupuuzwa kwa urahisi. Lugha za programu za ulimwengu halisi huwa na matukio makubwa yenye utekelezaji changamano, na hii inapunguza kasi ya majaribio. Hata hivyo, matokeo yoyote yanayotokana na lugha iliyorahisishwa yanaonekana kuwa ya kutiliwa shaka kidogo, kwani katika kupata matokeo haya mtafiti anaweza kujitolea mambo muhimu kwa matumizi ya lugha kimatendo.

Kikagua aina yangu ya Alore ilionekana kuwa ya kuahidi sana, lakini nilitaka kuijaribu kwa kujaribu na nambari halisi, ambayo, unaweza kusema, haikuandikwa kwa Alore. Kwa bahati nzuri kwangu, lugha ya Alore ilitegemea sana mawazo sawa na Python. Ilikuwa rahisi kutosha kutengeneza tena chapa ili iweze kufanya kazi na syntax na semantiki za Python. Hii ilituruhusu kujaribu kuangalia katika msimbo wa Python wa chanzo wazi. Kwa kuongezea, niliandika kibadilishaji cha kubadilisha nambari iliyoandikwa kwa Alore hadi nambari ya Python na kuitumia kutafsiri nambari yangu ya chapa. Sasa nilikuwa na mfumo wa kuangalia aina ulioandikwa katika Python ambao uliunga mkono sehemu ndogo ya Python, aina fulani ya lugha hiyo! (Maamuzi fulani ya usanifu ambayo yalikuwa na maana kwa Alore hayakufaa vizuri kwa Python, na hii bado inaonekana katika sehemu za mypy codebase.)

Kwa kweli, lugha inayoungwa mkono na mfumo wangu wa aina haikuweza kabisa kuitwa Python kwa wakati huu: ilikuwa ni lahaja ya Python kwa sababu ya mapungufu fulani ya syntax ya maelezo ya aina ya Python 3.

Ilionekana kama mchanganyiko wa Java na Python:

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

Mojawapo ya maoni yangu wakati huo ilikuwa kutumia maelezo ya aina kuboresha utendaji kwa kuunda aina hii ya Python hadi C, au labda JVM bytecode. Nilifika kwenye hatua ya kuandika mfano wa mkusanyaji, lakini niliachana na wazo hili, kwani ukaguzi wa aina yenyewe ulionekana kuwa muhimu sana.

Niliishia kuwasilisha mradi wangu katika PyCon 2013 huko Santa Clara. Nilizungumza pia juu ya hili na Guido van Rossum, dikteta wa Python mzuri kwa maisha yote. Alinishawishi kuacha sintaksia yangu mwenyewe na kushikamana na sintaksia ya kawaida ya Python 3. Python 3 inasaidia maelezo ya kazi, kwa hivyo mfano wangu unaweza kuandikwa upya kama inavyoonyeshwa hapa chini, na kusababisha programu ya kawaida ya Python:

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

Ilinibidi kufanya maelewano (kwanza kabisa, nataka kutambua kuwa niligundua syntax yangu mwenyewe kwa sababu hii). Hasa, Python 3.3, toleo la hivi karibuni la lugha wakati huo, halikuunga mkono ufafanuzi tofauti. Nilijadiliana na Guido kwa barua-pepe uwezekano mbalimbali wa muundo wa kisintaksia wa maelezo kama haya. Tuliamua kutumia maoni ya aina kwa anuwai. Hii ilitumikia kusudi lililokusudiwa, lakini ilikuwa ngumu kwa kiasi fulani (Python 3.6 ilitupa syntax nzuri zaidi):

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

Maoni ya aina pia yalikuja kusaidia kuunga mkono Python 2, ambayo haina usaidizi wa ndani wa maelezo ya aina:

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

Ilibadilika kuwa biashara hizi (na zingine) hazikuwa muhimu sana - faida za uchapaji tuli zilimaanisha kuwa watumiaji walisahau hivi karibuni kuhusu sintaksia ndogo kuliko-kamilifu. Kwa kuwa hakuna miundo maalum ya kisintaksia iliyotumiwa katika msimbo wa Python ulioangaliwa aina, zana zilizopo za Python na michakato ya usindikaji wa msimbo iliendelea kufanya kazi kwa kawaida, na kuifanya iwe rahisi zaidi kwa watengenezaji kujifunza zana mpya.

Guido pia alinishawishi nijiunge na Dropbox baada ya kukamilisha tasnifu yangu ya wahitimu. Hapa ndipo sehemu ya kuvutia zaidi ya hadithi ya mypy huanza.

Kuendelea ...

Ndugu wasomaji! Ikiwa unatumia Python, tafadhali tuambie kuhusu ukubwa wa miradi unayokuza katika lugha hii.

Njia ya kuangalia mistari milioni 4 ya nambari ya Python. Sehemu 1
Njia ya kuangalia mistari milioni 4 ya nambari ya Python. Sehemu 1

Chanzo: mapenzi.com

Kuongeza maoni