{"id":38479,"date":"2019-10-31T22:23:56","date_gmt":"2019-10-31T19:23:56","guid":{"rendered":"https:\/\/prohoster.info\/blog\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2\/"},"modified":"2019-10-31T22:23:56","modified_gmt":"2019-10-31T19:23:56","slug":"put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","status":"publish","type":"post","link":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","title":{"rendered":"Ce\u013c\u0161 uz 4 miljonu rindu Python koda tipu p\u0101rbaudi. Otr\u0101 da\u013ca","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>\u0160odien public\u0113jam otro da\u013cu par materi\u0101lu par to, k\u0101 Dropbox organiz\u0113ja tipu kontroli daudziem miljoniem Python kodu rindi\u0146u.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\"><img decoding=\"async\" alt=\"Ce\u013c\u0161 uz 4 miljonu rindu Python koda tipu p\u0101rbaudi. Otr\u0101 da\u013ca\" src=\"\/wp-content\/uploads\/2019\/09\/3f8f396d724153a0374a3fadca190d55.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u2192 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468233\/\">Las\u012bt pirmo da\u013cu<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Ofici\u0101l\u0101 tipu atbalsts (PEP 484)<\/h2>\n<p>\nM\u0113s veic\u0101m pirmos nopietnos eksperimentus ar mypy Dropbox laik\u0101 Hack Week 2014. Hack Week ir pas\u0101kums, ko Dropbox organiz\u0113 vienas ned\u0113\u013cas garum\u0101. \u0160aj\u0101 laik\u0101 darbinieki var str\u0101d\u0101t pie jebk\u0101! Da\u017ei no slaven\u0101kajiem tehnolo\u0123iju projektiem Dropbox s\u0101k\u0101s tie\u0161i \u0161ajos pas\u0101kumos. \u0160\u012b eksperimenta rezult\u0101t\u0101 m\u0113s non\u0101c\u0101m pie secin\u0101juma, ka mypy izskat\u0101s sol\u012bgi, lai gan \u0161is projekts v\u0113l nebija gatavs pla\u0161ai izmanto\u0161anai.<\/p>\n<p>Taj\u0101 laik\u0101 gais\u0101 virmoja ideja par Python tipu nor\u0101\u017eu sist\u0113mu standartiz\u0113\u0161anu. K\u0101 jau teicu, s\u0101kot no Python 3.0 bija iesp\u0113jams izmantot tipu anot\u0101cijas funkcij\u0101m, ta\u010du t\u0101s bija tikai nejau\u0161i izteikumi, bez defin\u0113ta sintakses un semantikas. Izpildes laik\u0101 \u0161\u012bs anot\u0101cijas liel\u0101koties tika vienk\u0101r\u0161i ignor\u0113tas. P\u0113c Hack Week m\u0113s s\u0101k\u0101m str\u0101d\u0101t pie semantikas standartiz\u0113\u0161anas. \u0160is darbs noveda pie <noindex><a rel=\"nofollow\" href=\"https:\/\/www.python.org\/dev\/peps\/pep-0484\/\">PEP 484<\/a><\/noindex> (uz \u0161o dokumentu kop\u012bgi str\u0101d\u0101ja Gvido van Rossum, Luka Lange un es).<\/p>\n<p>M\u016bsu motiv\u0101cija var\u0113ja tikt skat\u012bta no div\u0101m pus\u0113m. Pirmk\u0101rt, m\u0113s cer\u0113j\u0101m, ka visa Python ekosist\u0113ma var\u0113tu pie\u0146emt kop\u012bgu pieeju tipu nor\u0101\u017eu (type hints - termins, kas tiek izmantots Python k\u0101 analo\u0123ija \u201etipu anot\u0101cij\u0101m\u201d) izmanto\u0161anai. Tas, \u0146emot v\u0113r\u0101 iesp\u0113jamos riskus, b\u016btu lab\u0101k nek\u0101 izmantot daudzus savstarp\u0113ji nesavienojamus pieejas. Otrk\u0101rt, m\u0113s v\u0113l\u0113j\u0101mies atkl\u0101ti apspriest tipu anot\u0101cijas meh\u0101nismus ar daudziem Python kopienes p\u0101rst\u0101vjiem. Da\u013c\u0113ji \u0161o v\u0113lmi noteica tas, ka m\u0113s nev\u0113l\u0113j\u0101mies izskat\u012bties k\u0101 \u201enospied\u0113ji\u201d pret pamata valodas idej\u0101m pla\u0161\u0101 Python programm\u0113t\u0101ju ac\u012bs. Tas ir dinamiski tipiz\u0113ts valoda, kas paz\u012bstama ar \u201ep\u012bles tipiz\u0101ciju\u201d. Kopien\u0101, s\u0101kum\u0101 nevar\u0113ja neizcelties nedaudz aizdom\u012bga attieksme pret statisk\u0101s tipiz\u0101cijas ideju. Bet \u0161\u0101ds noska\u0146ojums galu gal\u0101 v\u0101j\u0101ks - p\u0113c tam, kad k\u013cuva skaidrs, ka statisk\u0101 tipiz\u0101cija netiek pl\u0101nota dar\u012bt oblig\u0101tu (un p\u0113c tam, kad cilv\u0113ki saprata, ka t\u0101 patie\u0161\u0101m ir noder\u012bga).<\/p>\n<p>Pie\u0146emtais sintakse veids bija \u013coti l\u012bdz\u012bgs tam, ko taj\u0101 laik\u0101 atbalst\u012bja mypy. PEP 484 dokuments tika izlaists kop\u0101 ar Python 3.5 2015. gad\u0101. Python vairs nebija valoda, kas atbalsta tikai dinamisko tipiz\u0101ciju. Man pat\u012bk dom\u0101t par \u0161o notikumu k\u0101 par noz\u012bm\u012bgu pagrieziena punktu Python v\u0113stur\u0113.<\/p>\n<h2>Migr\u0101cijas s\u0101kums<\/h2>\n<p>\n2015. gada beig\u0101s Dropbox tika izveidota tr\u012bs cilv\u0113ku komanda darbam pie mypy. Taj\u0101 bija Gvido van Rossum, Gregs Praiss un Deivids Fi\u0161ers. No \u0161\u012b br\u012b\u017ea situ\u0101cija s\u0101ka strauji att\u012bst\u012bties. Pirmais \u0161\u0137\u0113rslis mypy izaugsmei bija veiktsp\u0113ja. K\u0101 jau iepriek\u0161 min\u0113ju, agr\u012bnaj\u0101 projekta att\u012bst\u012bbas posm\u0101 es dom\u0101ju par mypy realiz\u0101cijas p\u0101rvieto\u0161anu uz C valodu, bet \u0161\u012b ideja tika atcelta. M\u0113s iestr\u0113g\u0101m ar to, ka sist\u0113mas palai\u0161anai tika izmantots CPython interpreters, kas nav pietiekami \u0101trs t\u0101diem r\u012bkiem k\u0101 mypy. (Projekts PyPy, alternat\u012bva Python realiz\u0101cija ar JIT kompilatoru, ar\u012b mums nepal\u012bdz\u0113ja.)<\/p>\n<p>Par laimi, \u0161eit mums pal\u012bg\u0101 n\u0101ca da\u017ei algoritmiskie uzlabojumi. Pirmais jaud\u012bgais \"pa\u0101trin\u0101t\u0101js\" bija inkrement\u0101l\u0101s p\u0101rbaudes realiz\u0101cija. \u0160\u012b uzlabojuma ideja bija vienk\u0101r\u0161a: ja kop\u0161 iepriek\u0161\u0113j\u0101s mypy palai\u0161anas visas modu\u013ca atkar\u012bbas nav main\u012bju\u0161\u0101s, tad m\u0113s varam izmantot, str\u0101d\u0101jot ar atkar\u012bb\u0101m, iepriek\u0161\u0113j\u0101 sesij\u0101 kaus\u0113tus datus. Mums bija nepiecie\u0161ams tikai veikt tipu p\u0101rbaudi main\u012btajos failos un failos, kas no tiem bija atkar\u012bgi. Mypy g\u0101ja pat v\u0113l t\u0101l\u0101k: ja modu\u013ca \u0101r\u0113j\u0101 saskarne nebija main\u012bjusies, mypy uzskat\u012bja, ka citi modu\u013ci, kas import\u0113 \u0161o moduli, nav j\u0101verific\u0113 atk\u0101rtoti.<\/p>\n<p>Inkr\u0113ment\u0101l\u0101 p\u0101rbaude \u013coti pal\u012bdz\u0113ja mums, anot\u0113jot lielus eso\u0161\u0101 koda apjomus. Proti, \u0161is process parasti ietver daudzas iterat\u012bvas mypy palai\u0161anas, jo anot\u0101cijas pak\u0101peniski tiek pievienotas kodam un pak\u0101peniski uzlabojas. Pirmais mypy palai\u0161ana joproj\u0101m bija \u013coti l\u0113na, jo t\u0101s izpildes laik\u0101 bija j\u0101p\u0101rbauda daudz atkar\u012bbu. T\u0101p\u0113c m\u0113s, lai uzlabotu situ\u0101ciju, \u012bstenoj\u0101m att\u0101lin\u0101t\u0101s ke\u0161atmi\u0146as meh\u0101nismu. Ja mypy atkl\u0101j, ka lok\u0101l\u0101 ke\u0161atmi\u0146a, iesp\u0113jams, ir novecojusi, tas lejupiel\u0101d\u0113 aktu\u0101lo ke\u0161atmi\u0146as att\u0113lu visai kodu b\u0101zei no centraliz\u0113t\u0101 repozitorija. P\u0113c tam tas veic, izmantojot \u0161o att\u0113lu, inkr\u0113ment\u0101lo p\u0101rbaudi. Tas bija v\u0113l viens b\u016btisks solis m\u016bsu ce\u013c\u0101 uz mypy veiktsp\u0113jas palielin\u0101\u0161anu.<\/p>\n<p>T\u0101 bija \u0101tras un dabiski ieviestas tipa p\u0101rbaudes sist\u0113mas ievie\u0161anas perioda Dropbox. Mums l\u012bdz 2016. gada beig\u0101m jau bija aptuveni 420000 rindu Python koda ar tipu anot\u0101cij\u0101m. Daudzi lietot\u0101ji ar entuziasmu uz\u0146\u0113ma tipu p\u0101rbaudi. Dropbox mypy arvien vair\u0101k izmantoja da\u017e\u0101das izstr\u0101d\u0101t\u0101ju komandas.<\/p>\n<p>Toreiz viss izskat\u012bj\u0101s labi, ta\u010du mums v\u0113l bija daudz dar\u0101m\u0101. M\u0113s s\u0101k\u0101m veikt periodiskus iek\u0161\u0113jus lietot\u0101ju aptaujas, lai identific\u0113tu projekta v\u0101j\u0101s vietas un saprastu, k\u0101das probl\u0113mas j\u0101risina vispirms (\u0161\u012b prakse tiek izmantota uz\u0146\u0113mum\u0101 ar\u012b m\u016bsdien\u0101s). Visdzi\u013c\u0101kais, k\u0101 izr\u0101d\u012bj\u0101s, bija divas uzdevumu grupas. Pirmais \u2014 nepiecie\u0161ams liel\u0101ks koda segums ar tipiem, otrais \u2014 nepiecie\u0161ams, lai mypy darbotos \u0101tr\u0101k. Piln\u012bgi skaidri bija tas, ka m\u016bsu darbs pie mypy pa\u0101trin\u0101\u0161anas un t\u0101 ievie\u0161anas uz\u0146\u0113muma projektos v\u0113l nebija pabeigts. Apzinoties \u0161o divu uzdevumu svar\u012bgumu, m\u0113s \u0137\u0113r\u0101mies pie to risin\u0101\u0161anas.<\/p>\n<h2>Vair\u0101k veiktsp\u0113jas!<\/h2>\n<p>\nInkriment\u0101l\u0101s p\u0101rbaudes pa\u0101trin\u0101ja mypy, ta\u010du \u0161is r\u012bks joproj\u0101m nebija pietiekami \u0101trs. Daudzas inkriment\u0101l\u0101s p\u0101rbaudes aiz\u0146\u0113ma aptuveni min\u016bti. Iemesls tam bija cikliskie importi. Tas, iesp\u0113jams, nep\u0101rsteigs tos, kuri ir str\u0101d\u0101ju\u0161i ar liel\u0101m Python kodu b\u0101z\u0113m. Mums bija simtiem modu\u013cu, no kuriem katrs netie\u0161i import\u0113ja visus p\u0101r\u0113jos. Ja jebkur\u0161 fails cikla importos tika main\u012bts, mypy n\u0101c\u0101s apstr\u0101d\u0101t visus failus, kas bija ietverti \u0161aj\u0101 cikl\u0101, un bie\u017ei v\u0113l ar\u012b jebk\u0101dus modu\u013cus, kas import\u0113ja modu\u013cus no \u0161\u012b cikla. Viens no \u0161iem cikliem bija slavenais \u201eatkar\u012bbu mezgls\u201c, kas rad\u012bja daudz nepatik\u0161anu Dropbox. Reiz \u0161\u012b strukt\u016bra ietv\u0113ra vair\u0101kus simtus modu\u013cu, un to import\u0113ja, tie\u0161i vai netie\u0161i, daudzi testi, k\u0101 ar\u012b to izmantoja produkcijas kod\u0101.<\/p>\n<p>M\u0113s apsv\u0113ra iesp\u0113ju \u201eatrais\u012bt\u201d ciklisk\u0101s atkar\u012bbas, ta\u010du mums nebija resursu to izdar\u012bt. Tur bija p\u0101r\u0101k daudz koda, ar kuru m\u0113s nebij\u0101m paz\u012bstami. Galu gal\u0101 m\u0113s izv\u0113l\u0113j\u0101mies alternat\u012bvu pieeju. M\u0113s nol\u0113m\u0101m pan\u0101kt, lai mypy darbotos \u0101tri pat tad, ja ir \u201eatkar\u012bbu mezgli\u201d. M\u0113s sasniedz\u0101m \u0161o m\u0113r\u0137i ar mypy dmeonu. Dmeons ir servera process, kas \u012bsteno divas interesantas iesp\u0113jas. Pirmk\u0101rt \u2013 tas saglab\u0101 visus kodu b\u0101zes datus atmi\u0146\u0101. Tas noz\u012bm\u0113, ka katru reizi, palai\u017eot mypy, nav j\u0101iel\u0101d\u0113 ke\u0161atmi\u0146\u0101 eso\u0161ie dati, kas saist\u012bti ar t\u016bksto\u0161iem import\u0113to atkar\u012bbu. Otrk\u0101rt \u2013 tas r\u016bp\u012bgi anal\u012bz\u0113 attiec\u012bbas starp funkcij\u0101m un cit\u0101m ent\u012btij\u0101m s\u012bku strukt\u016bru l\u012bmen\u012b. Piem\u0113ram, ja funkcija <code>foo<\/code> izsauc funkciju <code>bar<\/code>, tad ir atkar\u012bba <code>foo<\/code> no <code>bar<\/code>. Kad fails tiek main\u012bts, dmeons vispirms atsevi\u0161\u0137i apstr\u0101d\u0101 tikai main\u012bto failu. P\u0113c tam tas apl\u016bko \u0161\u012b faila izmai\u0146as, kas ir redzamas no \u0101rpuses, piem\u0113ram, main\u012bt\u0101s funkciju paraksti. Dmeons izmanto detaliz\u0113tu inform\u0101ciju par importiem tikai, lai p\u0101rbaud\u012btu t\u0101s funkcijas, kuras faktiski izmanto main\u012bto funkciju. Parasti \u0161\u0101das pieejas gad\u012bjum\u0101 j\u0101p\u0101rbauda sal\u012bdzino\u0161i maz funkciju.<\/p>\n<p>Visu \u0161o \u012bsteno\u0161ana bija sare\u017e\u0123\u012bta, jo s\u0101kotn\u0113j\u0101 mypy realiz\u0101cija bija \u013coti v\u0113rsta uz viena faila apstr\u0101di vienlaic\u012bgi. Mums n\u0101c\u0101s saskarties ar daudz\u0101m robe\u017esitu\u0101cij\u0101m, kuru ra\u0161an\u0101s pras\u012bja atk\u0101rtotas p\u0101rbaudes, kad kod\u0101 tika veiktas izmai\u0146as. Piem\u0113ram, tas notiek, kad klasei tiek pie\u0161\u0137irta jauna pamatklase. P\u0113c tam, kad m\u0113s izdar\u012bj\u0101m to, ko v\u0113l\u0113j\u0101mies, m\u0113s sp\u0113jam samazin\u0101t vairuma inkrement\u0101lo p\u0101rbaudes laiku l\u012bdz da\u017e\u0101m sekund\u0113m. Mums tas \u0161\u0137ita liels sasniegums.<\/p>\n<h2>V\u0113l liel\u0101ka veiktsp\u0113ja!<\/h2>\n<p>\nKop\u0101 ar att\u0101lin\u0101to ke\u0161atmi\u0146u, par kuru es iepriek\u0161 run\u0101ju, mypy demonstrators praktiski piln\u012bb\u0101 atrisin\u0101ja probl\u0113mas, kas rad\u0101s, kad programm\u0113t\u0101js bie\u017ei veic tipu p\u0101rbaudi, veicot izmai\u0146as neliel\u0101 failu skait\u0101. Tom\u0113r sist\u0113mas veiktsp\u0113ja, visneizdev\u012bg\u0101kaj\u0101 t\u0101s izmanto\u0161anas scen\u0101rij\u0101, joproj\u0101m bija t\u0101lu no optim\u0101l\u0101s. T\u012bra mypy palai\u0161ana var\u0113ja aiz\u0146emt vair\u0101k nek\u0101 15 min\u016btes. Un tas bija daudz vair\u0101k, nek\u0101 m\u016bs apmierin\u0101tu. Katru ned\u0113\u013cu situ\u0101cija k\u013cuva aizvien slikt\u0101ka, jo programm\u0113t\u0101ji turpin\u0101ja rakst\u012bt jaunu kodu un pievienot anot\u0101cijas eso\u0161ajam kodam. M\u016bsu lietot\u0101ji joproj\u0101m ilgoj\u0101s p\u0113c liel\u0101kas veiktsp\u0113jas, un m\u0113s ar prieku bij\u0101m gatavi vi\u0146iem pal\u012bdz\u0113t.<\/p>\n<p>M\u0113s nol\u0113m\u0101m atgriezties pie vienas no agr\u0101kaj\u0101m idej\u0101m par mypy. Proti, par Python koda p\u0101rv\u0113r\u0161anu C kod\u0101. Eksperimenti ar Cython (kas ir sist\u0113ma, kas \u013cauj tulkot Python rakst\u012btu kodu C kod\u0101) mums deva maz redzamu uzlabojumu, t\u0101d\u0113\u013c m\u0113s nol\u0113m\u0101m atdz\u012bvin\u0101t ideju par sava kompilatora rakst\u012b\u0161anu. T\u0101 k\u0101 mypy kodu b\u0101ze (rakst\u012bta Python) jau ietv\u0113ra visas nepiecie\u0161am\u0101s tipu anot\u0101cijas, mums lik\u0101s v\u0113rts m\u0113\u0123in\u0101t izmantot \u0161\u012bs anot\u0101cijas, lai pa\u0101trin\u0101tu sist\u0113mas darb\u012bbu. Es \u0101tri izveidoju prototipu, lai p\u0101rbaud\u012btu \u0161o ideju. Tas r\u0101d\u012bja vair\u0101k nek\u0101 desmitk\u0101rt\u012bgu veiktsp\u0113jas pieaugumu da\u017e\u0101dos mikro-benchmarks. M\u016bsu ideja bija kompil\u0113t Python modu\u013cus C modu\u013cos, izmantojot Cython, un p\u0101rv\u0113rst tipu anot\u0101cijas par tipu p\u0101rbaud\u0113m, kas tiek veiktas programmas izpildes laik\u0101 (parasti tipu anot\u0101cijas programm\u0101 tiek ignor\u0113tas izpildes laik\u0101 un tiek izmantotas tikai tipu p\u0101rbaudes sist\u0113m\u0101s). M\u0113s faktiski pl\u0101noj\u0101m p\u0101rv\u0113rst mypy realiz\u0101ciju no Python uz valodu, kas ir statiski tipiz\u0113ta, kas izskat\u012btos (un liel\u0101koties darbotos) tie\u0161i t\u0101pat k\u0101 Python. (\u0160is interlangu \u0123en\u0113zes variants k\u013cuva par kaut k\u0101du trad\u012bciju mypy projekt\u0101. S\u0101kotn\u0113j\u0101 mypy realiz\u0101cija tika rakst\u012bta Alore, p\u0113c tam bija sintaktisks hibr\u012bds starp Java un Python).<\/p>\n<p>Orient\u0101cija uz CPython papla\u0161in\u0101jumu API bija atsl\u0113ga, lai nezaud\u0113tu projekta p\u0101rvald\u012bbas iesp\u0113jas. Mums nebija j\u0101realiz\u0113 virtu\u0101l\u0101 ma\u0161\u012bna vai jebkuras bibliot\u0113kas, kas bija nepiecie\u0161amas mypy. Turkl\u0101t m\u0113s joproj\u0101m var\u0113j\u0101m piek\u013c\u016bt visai Python ekosist\u0113mai, visi r\u012bki (piem\u0113ram, pytest) b\u016btu pieejami. Tas noz\u012bm\u0113ja, ka m\u0113s var\u0113j\u0101m turpin\u0101t izmantot interpret\u0113to Python kodu izstr\u0101des laik\u0101, kas \u013cautu mums turpin\u0101t darbu, izmantojot \u013coti \u0101tru kodu labojumu un test\u0113\u0161anas sh\u0113mu, nevis gaid\u012bt koda kompil\u0101ciju. Izskat\u012bj\u0101s, ka mums lieliski izdodas, t\u0101 sakot, s\u0113d\u0113t uz diviem kr\u0113sliem, un m\u0113s to baud\u012bj\u0101m.<\/p>\n<p>Kompilators, ko m\u0113s nosauc\u0101m par mypyc (jo tas k\u0101 frontend izmanto mypy tipu anal\u012bzei), izr\u0101d\u012bj\u0101s sam\u0113r\u0101 veiksm\u012bgs projekts. Kopum\u0101 m\u0113s sasniedz\u0101m aptuveni 4 reizes \u0101tr\u0101kus mypy izsaukumus bez ke\u0161o\u0161anas izmanto\u0161anas. Mypyc projekta kodola izstr\u0101dei nelielai komandai, kur\u0101 ietilpa Maikls Salivans, Ivans Levkivskis, Hj\u016b Hens un es, bija nepiecie\u0161ami apm\u0113ram 4 kalend\u0101ra m\u0113ne\u0161i. \u0160is darba apjoms bija daudz maz\u0101ks nek\u0101 tas, kas b\u016btu vajadz\u012bgs, lai p\u0101rrakst\u012btu mypy, piem\u0113ram, uz C++ vai Go. Un ar\u012b izmai\u0146u skaits, ko mums vajadz\u0113ja ieviest projekt\u0101, bija krietni maz\u0101ks, nek\u0101 tas b\u016btu nepiecie\u0161ams, p\u0101rrakstot to cit\u0101 valod\u0101. M\u0113s, turkl\u0101t, cer\u0113j\u0101m, ka var\u0113sim mypyc aizvest l\u012bdz t\u0101dam l\u012bmenim, lai to var\u0113tu izmantot, lai kompil\u0113tu un pa\u0101trin\u0101tu savu kodu, ar\u012b citi Dropbox programm\u0113t\u0101ji.<\/p>\n<p>Lai sasniegtu \u0161\u0101du veiktsp\u0113ju, mums n\u0101c\u0101s pielietot da\u017eus interesantus in\u017eeniertehniskus risin\u0101jumus. Piem\u0113ram, kompilators sp\u0113j pa\u0101trin\u0101t daudzas oper\u0101cijas, izmantojot \u0101tr\u0101s zem\u0101 l\u012bme\u0146a C konstrukcijas. Piem\u0113ram, izsaukums uz kompil\u0113tu funkciju tiek p\u0101rv\u0113rsts par izsaukumu uz C funkciju. Un t\u0101ds izsaukums tiek veikts daudz \u0101tr\u0101k nek\u0101 interpret\u0113t\u0101 funkcija. Da\u017eas oper\u0101cijas, t\u0101das k\u0101 mekl\u0113\u0161ana v\u0101rdn\u012bc\u0101s, joproj\u0101m palika pie parastajiem C-API izsaukumiem no CPython, kas p\u0113c kompil\u0101cijas izr\u0101d\u012bj\u0101s tikai nedaudz \u0101tr\u0101kas. M\u0113s sp\u0113jam atbr\u012bvoties no papildu slodzes uz sist\u0113mu, ko rad\u012bja interpret\u0101cija, ta\u010du \u0161aj\u0101 gad\u012bjum\u0101 tas sniedza tikai nelielu pe\u013c\u0146u veiktsp\u0113j\u0101.<\/p>\n<p>Lai identific\u0113tu visizplat\u012bt\u0101k\u0101s \"l\u0113n\u0101s\" oper\u0101cijas, m\u0113s veic\u0101m koda profil\u0113\u0161anu. Ar ieg\u016btajiem datiem m\u0113s cent\u0101mies vai nu uzlabot mypyc, lai tas \u0123ener\u0113tu \u0101tr\u0101ku C kodu \u0161\u0101d\u0101m oper\u0101cij\u0101m, vai p\u0101rrakst\u012bt atbilsto\u0161o Python kodu, izmantojot \u0101tr\u0101kas oper\u0101cijas (da\u017ereiz mums vienk\u0101r\u0161i nebija pietiekami vienk\u0101r\u0161a risin\u0101juma \u0161ai vai tai probl\u0113mai). Python koda p\u0101rrakst\u012b\u0161ana bie\u017ei izr\u0101d\u012bj\u0101s viegl\u0101ks risin\u0101jums probl\u0113mai nek\u0101 autom\u0101tiska t\u0101 pa\u0161a transform\u0101cijas \u012bsteno\u0161ana kompilator\u0101. Ilgtermi\u0146\u0101 m\u0113s v\u0113l\u0113j\u0101mies automatiz\u0113t daudzas no \u0161\u012bm transform\u0101cij\u0101m, bet taj\u0101 br\u012bd\u012b m\u0113s fokus\u0113j\u0101mies uz to, lai ar minim\u0101lu piep\u016bli pa\u0101trin\u0101tu mypy. Un, virzoties uz \u0161o m\u0113r\u0137i, m\u0113s izgriez\u0101m da\u017eus st\u016br\u012b\u0161us.<\/p>\n<p>Turpin\u0101jums sekos\u2026<\/p>\n<p><b>Cien\u012bjamie las\u012bt\u0101ji!<\/b> K\u0101das bija j\u016bsu saj\u016btas par mypy projektu, kad uzzin\u0101j\u0101t par t\u0101 past\u0101v\u0113\u0161anu?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Ce\u013c\u0161 uz 4 miljonu rindu Python koda tipu p\u0101rbaudi. Otr\u0101 da\u013ca\" src=\"\/wp-content\/uploads\/2019\/09\/e3c1dd40228b56d0196fd65e4df22a59.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/#order\"><img decoding=\"async\" alt=\"Ce\u013c\u0161 uz 4 miljonu rindu Python koda tipu p\u0101rbaudi. Otr\u0101 da\u013ca\" src=\"\/wp-content\/uploads\/2019\/09\/263173dd3ab487da330ff9063e3c180e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Avots: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432 Dropbox \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0442\u0438\u043f\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u2192 \u0427\u0438\u0442\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u041e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0442\u0438\u043f\u043e\u0432 (PEP 484) \u041c\u044b \u043f\u0440\u043e\u0432\u0435\u043b\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u044b\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u044b \u0441 mypy \u0432 Dropbox \u0432\u043e \u0432\u0440\u0435\u043c\u044f Hack Week 2014. Hack Week \u2014 \u044d\u0442\u043e \u043c\u0435\u0440\u043e\u043f\u0440\u0438\u044f\u0442\u0438\u0435, \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043c\u043e\u0435 Dropbox \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u043d\u0435\u0434\u0435\u043b\u0438. \u0412 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28879,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-38479","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432 Dropbox \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0442\u0438\u043f\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"lv_LV\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0443\u0442\u044c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u0427\u0430\u0441\u0442\u044c 2 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432 Dropbox \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0442\u0438\u043f\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:23:56+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:23:56+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Ce\u013c\u0161 l\u012bdz tipu p\u0101rbaud\u012b\u0161anai 4 miljonu rindu Python koda. 2. da\u013ca | ProHoster","description":"\u0160odien public\u0113jam otro da\u013cu par materi\u0101lu par to, k\u0101 Dropbox organiz\u0113ja tipu kontroli daudziem miljoniem Python kodu rindi\u0146u.","canonical_url":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"lv_LV","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0443\u0442\u044c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u0427\u0430\u0441\u0442\u044c 2 | ProHoster","og:description":"\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432 Dropbox \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0442\u0438\u043f\u043e\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430.","og:url":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:23:56+00:00","article:modified_time":"2019-10-31T19:23:56+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38479","title":null,"description":null,"keywords":null,"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 22:13:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:08:32","updated":"2026-08-11 12:50:31","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts\/38479","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/comments?post=38479"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts\/38479\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/media\/28879"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/media?parent=38479"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/categories?post=38479"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/tags?post=38479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}