Sot tani po ju sjellim pjesën e parë të përkthimit të materialit mbi mënyrën se si Dropbox kontrollon tipet në kodin Python.
NĂ« Dropbox shkrimi nĂ« Python Ă«shtĂ« shumĂ« i zakonshĂ«m. Ky Ă«shtĂ« njĂ« gjuhĂ« qĂ« e pĂ«rdorim jashtĂ«zakonisht gjerĂ« â si pĂ«r shĂ«rbimet e backend-it, ashtu edhe pĂ«r aplikacionet klientore nĂ« desktop. Gjithashtu, ne pĂ«rdorim shumĂ« Go, TypeScript dhe Rust, por Python Ă«shtĂ« gjuha jonĂ« kryesore. Duke marrĂ« parasysh pĂ«rmasat tona, qĂ« lidhen me miliona rreshta kodi Python, doli se tipizimi dinamik i kĂ«tij kodi e ka komplikuar pa nevojĂ« kuptimin e tij dhe filloi tĂ« ndikonte seriozisht nĂ« produktivitetin e punĂ«s. PĂ«r tĂ« lehtĂ«suar kĂ«tĂ« problem, ne filluam njĂ« proces tĂ« gradual tĂ« kalimit tĂ« kodit tonĂ« nĂ« kontrollin statik tĂ« tipeve duke pĂ«rdorur mypy. Ky Ă«shtĂ«, ndoshta, sistemi mĂ« i njohur i pavarur i verifikimit tĂ« tipeve pĂ«r Python. Mypy Ă«shtĂ« njĂ« projekt me kod tĂ« hapur, me zhvilluesit e saj kryesorĂ« qĂ« punojnĂ« nĂ« Dropbox.
Dropbox ishte njĂ« nga kompanitĂ« e para qĂ« implementoi kontrollin statik tĂ« tipeve nĂ« kodin Python nĂ« njĂ« shkallĂ« tĂ« tillĂ«. Sot, mypy pĂ«rdoret nĂ« mijĂ«ra projekte. Ky instrument Ă«shtĂ« provuar nĂ« mija raste, ose siç thuhet, "testuar nĂ« betejĂ«". Ne, pĂ«r tĂ« arritur aty ku jemi tani, kaluam njĂ« rrugĂ« tĂ« gjatĂ«. GjatĂ« kĂ«saj rruge pati jo pak pĂ«rpjekje tĂ« dĂ«shtuar dhe eksperimente tĂ« dĂ«shtuara. Ky material rrĂ«fen historinĂ« e kontrollit statik tĂ« tipeve nĂ« Python â nga fillimi i tij i vĂ«shtirĂ«, qĂ« ishte pjesĂ« e projektit tim kĂ«rkimor, deri nĂ« ditĂ«t e sotme, kur verifikimet e tipeve dhe sugjerimet pĂ«r tipe janĂ« bĂ«rĂ« normale pĂ«r njĂ« numĂ«r tĂ« pallogaritshĂ«m zhvilluesish qĂ« shkruajnĂ« nĂ« Python. KĂ«to mekanizma tani mbĂ«shteten nga shumĂ« mjete â si IDE dhe analizuesit e kodit.
â
Përse nevojitet kontrolli i tipeve?
NĂ«se ndonjĂ«herĂ« keni pĂ«rdorur Python qĂ« ka tipe dinamike, mund tĂ« keni pak paqartĂ«si se pse ka kaq shumĂ« zhurmĂ« rreth tipeve statike dhe mypy kohĂ«t e fundit. Ndoshta ju pĂ«lqen Python pikĂ«risht pĂ«r shkak tĂ« tipizimit tĂ« tij dinamik, dhe kjo gjĂ« qĂ« po ndodh ju shqetĂ«son. ĂelĂ«si i vlerĂ«s sĂ« tipizimit statik Ă«shtĂ« shkalla e zgjidhjeve: sa mĂ« i madh tĂ« jetĂ« projekti juaj, aq mĂ« shumĂ« do tĂ« prireni drejt tipizimit statik dhe, pĂ«rfundimisht, aq mĂ« shumĂ« do ta keni nevojĂ« kĂ«tĂ« nĂ« tĂ« vĂ«rtetĂ«.
Supozoni se një projekt ka arritur në disa dhjetëra mijëra rreshta dhe doli se mbi të po punojnë disa programues. Ndërsa shqyrtojmë një projekt të tillë, bazuar në përvojën tonë, mund të themi se kuptimi i kodit të tij do të jetë çelësi për mbështetje produktiviteti të zhvilluesve. Pa anotime tipore, ndonjëherë është e vështirë të kuptohet, për shembull, se cilat argumente duhet t'i kaloni funksionit, ose se cilat tipe vlerash mund të kthejë një funksion. Këtu janë pyetje tipike, të cilave shpesh është e vështirë të përgjigjeni pa përdorur anotime tipore:
- A mund të kthejë ky funksion
AsnjĂ«? - ĂfarĂ« duhet tĂ« jetĂ« ky argument
artikuj? - Cili është tipi i atributit
id:intapo është,str, ose ndoshta një tip personalizuar? - A duhet të jetë ky argument një listë? A mund të kalosh një tuple në të?
Nëse e shikoni fragmentin e mëposhtëm të kodit, i cili është i pajisur me annotime tipash, dhe përpiqeni të përgjigjeni në pyetje të tilla, do të mendoni se është një detyrë e thjeshtë:
class Resource:
id: bytes
...
def read_metadata(self,
items: Sequence[str]) -> Dict[str, MetadataItem]:
...read_metadatanuk kthenAsnjĂ«, pasi tipi i kthimit nuk Ă«shtĂ«Optional[âŠ].- Argumenti
artikujështë një sekuencë strings. Nuk mund të iterohet në rend të rastit. - Atributi
idështë një varg bajtesh.
Në një botë ideale, do të pritej që të gjitha hollësitë e tilla të ishin të përshkruara në dokumentacionin e brendshëm (docstring). Por, përvoja ofron shumë shembuj që dokumentacioni i tillë shpesh mungon në kodin me të cilin punojmë. Edhe nëse një dokumentacion i tillë ekziston, nuk mund të presim që ai të jetë absolutisht i saktë. Ky dokumentacion mund të jetë i paqartë, i pasaktë dhe të lërë shumë mundësi për keqkuptime. Në ekipet e mëdha ose në projekte të mëdha, ky problem mund të bëhet jashtëzakonisht i ndjeshëm.
Ndërsa Python tregon performancë të shkëlqyer në fazat e hershme ose ndërmjet projekteve, në një moment të caktuar, projektet e suksesshme dhe kompanitë që përdorin Python mund të përballen me një pyetje jetësore: "Na nevojitet ta rishkruajmë gjithçka në një gjuhë me tipizim statik?"
Sistemet e verifikimit të tipeve simotike me mypy e zgjidhin këtë problem duke ofruar një gjuhë formale për zhvilluesit për të përshkruar llojet dhe duke verifikuar se përshkrimet e tipeve përputhen me realizimet e programeve (dhe, jo domosdoshmërisht, verifikojnë ekzistencën e tyre). Në përgjithësi, mund të thuhet se këto sisteme na japin diçka si një dokumentacion të kontrolluar me kujdes.
Përdorimi i këtyre sistemeve ka dhe avantazhe të tjera, dhe ato janë krejtësisht të rëndësishme:
- Sistemi i verifikimit të tipeve mund të zbulojë disa gabime të vogla (edhe jo aq të vogla). Një shembull tipik është kur harrohet të trajtohet një vlerë
Asnjëose një kusht tjetër të veçantë. - Refaktorizimi i kodit bëhet ndjeshëm më i lehtë, pasi sistemi i verifikimit të tipeve shpesh tregon shumë saktë se cili kod duhet të ndryshohet. Në të njëjtën kohë, nuk kemi nevojë të mbështetemi në një mbulim 100% të kodit me teste, gjë që, në çdo rast, zakonisht është e pamundur. Nuk kemi nevojë të studiojmë thellësitë e raporteve të gjurmimit të stackut për të zbuluar shkakun e defektit.
- Edhe në projekte të mëdha, mypy shpesh mund të kryejë një kontroll të plotë të tipeve në fraksione sekondash. Ndërsa ekzekutimi i testeve zakonisht kërkon dhjetëra sekonda ose madje minuta. Sistemi i kontrollit të tipeve ofron programuesit reagim të menjëhershëm dhe i lejon atij të punojë më shpejt. Nuk është e nevojshme më të shkruajë teste modulare të brishta dhe të vështira për t'u mbajtur, të cilat zëvendësojnë entitetet reale me mok-ët dhe patch-ët vetëm për të marrë rezultatet e provave të kodit më shpejt.
IDE-të dhe redaktorët, si PyCharm ose Visual Studio Code, përdorin mundësitë e annotation e tipeve për të ofruar zhvilluesve mundësi për përfundimin automatik të kodit, për theksimin e gabimeve dhe për mbështetje të konstruksioneve të zakonshme gjuhësore. Dhe këto janë vetëm disa nga përfitimet që ofron tipizimi. Për disa programues, gjitha këto janë argumenti kryesor në favor të tipizimit. Kjo është diçka që sjell dobi menjëherë pas zbatimit në punë. Ky rast përdorimi i tipeve nuk kërkon përdorimin e një sistemi të veçantë të kontrollit të tipeve, si mypy, megjithatë duhet të theksohet se mypy ndihmon në ruajtjen e përputhshmërisë midis annotation e tipeve dhe kodit.
Historia e mypy
Historia e mypy filloi nĂ« BritaninĂ« e Madhe, nĂ« Kembrixh, disa vite para se tĂ« bashkohesha me Dropbox. GjatĂ« studimeve pĂ«r doktoraturĂ«, merresha me çështjen e unifikimit tĂ« gjuhĂ«ve tĂ« tipizuar statikisht dhe dinamikisht. MĂ« frymĂ«zoi njĂ« artikull mbi tipizimin gradual nga Jeremy Siek dhe Walid Taha, si dhe projekti Typed Racket. PĂ«rpiqesha tĂ« gjeja mĂ«nyra pĂ«r tĂ« pĂ«rdorur tĂ« njĂ«jtĂ«n gjuhĂ« programimi pĂ«r projekte tĂ« ndryshme â nga skriptet e vogla, deri te baza tĂ« kodit qĂ« pĂ«rbĂ«heshin nga miliona rreshta. Gjithashtu, doja qĂ« nĂ« projektin e çdo shkalle, tĂ« mos ishte e nevojshme tĂ« bĂ«ja kompromise shumĂ« tĂ« mĂ«dha. NjĂ« pjesĂ« e rĂ«ndĂ«sishme e kĂ«saj ishte ideja pĂ«r njĂ« kalim gradual nga njĂ« prototip pa tipizim nĂ« njĂ« produkt tĂ« gatshĂ«m, tĂ« testuar nĂ« mĂ«nyrĂ« tĂ« plotĂ« dhe me tipizim statik. Sot, kĂ«to ide priten si tĂ« natyrshme, por nĂ« vitin 2010, kjo ishte njĂ« çështje qĂ« ende po hulumtohej aktivisht.
Puna ime fillestare në verificimin e tipeve nuk ishte fokusuar në Python. Në vend të saj, përdorja një gjuhë të vogël 'të bërë vetë' . Ky është një shembull që do t'ju ndihmojë të kuptoni për çfarë bëhet fjalë (annotimet e llojeve këtu nuk janë të detyrueshme):
def Fib(n as Int) as Int
if n <= 1
return n
else
return Fib(n - 1) + Fib(n - 2)
end
endPërdorimi i një gjuhe të thjeshtuar të zhvilluar në mënyrë të vetme është një qasje e zakonshme në kërkimin shkencor. Kjo është veçanërisht për shkak se kjo mundëson kryerjen e eksperimenteve më shpejt, si dhe që ajo që nuk ka të bëjë me kërkimin mund të injorohet lehtësisht. Gjuha të cilat përdoren në praktikë zakonisht janë fenomene masive me implementime komplekse, dhe kjo ngadalëson eksperimente. Megjithatë, çdo rezultat i bazuar në një gjuhë të thjeshtuar duket pak i dyshimtë, pasi kur arrijnë këto rezultate, mund të jetë se hulumtuesi ka sakrifikuar konsiderata të rëndësishme për përdorimin praktik të gjuhëve.
Mjeti im për verifikimin e tipeve për Alore dukej shumë premtues, por doja ta testoja atë duke kryer eksperimente me kodin real, të cilin, mund të thuhet, Alore nuk e kishte. Për fat të mirë, gjuha Alore ishte në masë të madhe e bazuar në idetë e njëjta si Python. Ishte mjaft e lehtë ta riformuloja mjetin për verifikimin e tipeve në mënyrë që të funksiononte me sintaksën dhe semantikën e Python. Kjo më lejoi të provoja të kryej verifikimin e tipeve në kodin open-source të Python. Për më tepër, shkrova një transpajler për të transformuar kodin e shkruar në Alore në kod Python dhe e përdora atë për të transmetuar kodin e mjetit tim për verifikimin e tipeve. Tani kisha një sistem për verifikimin e tipeve të shkruar në Python, i cili mbante një nëngrup të Python, një lloj të këtij gjuhe! (Disa vendime arkitektonike që kishin kuptim për Alore, nuk i përshtatnin mirë Python, kjo gjithashtu duket ende në disa pjesë të bazës së kodit mypy.)
Në të vërtetë, gjuha që mbështetet nga sistemi im i tipeve nuk mund të quhej Python në këtë moment: ishte një variant i Python për shkak të disa kufizimeve të sintaksës së tipave të Python 3.
Duhej të dukej si një përzierje e Java dhe Python:
int fib(int n):
    if n <= 1:
        return n
    else:
        return fib(n - 1) + fib(n - 2)Një nga idetë e mia në atë kohë ishte të përdorja anotimet e tipeve për të përmirësuar performancën duke kompiluar këtë variant të Python në C, ose ndoshta në kodin bajt të JVM. Arrita në fazën e hartimit të një prototipi të kompilerit, por e ndava këtë projekt, pasi kontrolli i tipeve vetë dukej mjaft i dobishëm.
Në fund, prezantova projektin tim në konferencën PyCon 2013 në Santa Clara. Po ashtu, bisedova për këtë me Guido van Rossum, diktatorin e përjetshëm dhe bujar të Python. Ai më bind të heq dorë nga sintaksa ime dhe të ndjek sintaksën standarde të Python 3. Python 3 mbështet anotimet e funksioneve, si rezultat, shembulli im mund të rishkruhej siç është treguar më poshtë, duke marrë një program normal Python:
def fib(n: int) -> int:
if n <= 1:
return n
else:
return fib(n - 1) + fib(n - 2)Më duhej të bënja disa kompromise (dëshiroj të theksoj se unë shpika sintaksën time për këtë arsye). Në veçanti, Python 3.3, versioni më i ri i gjuhës në atë kohë, nuk mbështeste shënimet për variablat. Kam biseduar me Guido përmes emailit mbi mundësi të ndryshme për dizajnin sintaksor të këtyre shënimeve. Ne vendosëm të përdorim komente për variablat që tregonin llojet. Kjo lejonte të arrinim qëllimin, por duke e bërë pamjen paksa të ngarkuar (Python 3.6 na dha një sintaksë më të këndshme):
produkti = [] # type: List[str] # EwwKomentet me lloje gjithashtu ishin të dobishme për mbështetje në Python 2, në të cilin nuk kishte mbështetje të integruar për shënimet e llojeve:
f fib(n):
# type: (int) -> int
if n <= 1:
return n
else:
return fib(n - 1) + fib(n - 2)KĂ«to (dhe kompromise tĂ« tjera) nĂ« tĂ« vĂ«rtetĂ« nuk ishin tĂ« rĂ«ndĂ«sishme â pĂ«rfitimet e tipizimit statik çuan nĂ« atĂ« qĂ« pĂ«rdoruesit shpejt i harruan sintaksĂ«n e pakĂ«t tĂ« pĂ«rsosur. Duke qenĂ« se tani nĂ« kodin Python, ku kontrolloheshin tipet, nuk aplikohej ndonjĂ« konstrukcion sintaksor i veçantĂ«, mjetet dhe proceset ekzistuese tĂ« Python pĂ«r pĂ«rpunimin e kodit vazhduan tĂ« punonin normalisht, gjĂ« qĂ« e bĂ«ri shumĂ« mĂ« tĂ« lehtĂ« mĂ«simin e kĂ«tij instrumenti nga zhvilluesit.
Guido, përveç kësaj, më bindë të bashkohem me Dropbox pasi mbrojta punimin tim përfundimtar. Këtu fillon historia më interesante e mypy.
VazhdonâŠ
TĂ« nderuar lexues! NĂ«se pĂ«rdorni Python â ju lutemi na tregoni pĂ«r projektet e çfarĂ« shkalle po zhvilloni nĂ« kĂ«tĂ« gjuhĂ«.
Burimi: habr.com
