{"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\/sk\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","title":{"rendered":"Cesta k overeniu typov 4 mili\u00f3nov riadkov k\u00f3du v Pythone. \u010cas\u0165 2","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Dnes zverej\u0148ujeme druh\u00fa \u010das\u0165 prekladu materi\u00e1lu o tom, ako v Dropboxe organizovali kontrolu typov nieko\u013ek\u00fdch mili\u00f3nov riadkov Python k\u00f3du.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\"><img decoding=\"async\" alt=\"Cesta k overeniu typov 4 mili\u00f3nov riadkov k\u00f3du v Pythone. \u010cas\u0165 2\" 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\/\">Pre\u010d\u00edta\u0165 prv\u00fa \u010das\u0165<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Ofici\u00e1lna podpora typov (PEP 484)<\/h2>\n<p>\nPrv\u00e9 v\u00e1\u017ene experimenty s mypy sme uskuto\u010dnili v Dropboxe po\u010das Hack Weeku 2014. Hack Week je podujatie, ktor\u00e9 sa uskuto\u010d\u0148uje v Dropboxe po\u010das jedn\u00e9ho t\u00fd\u017ed\u0148a. V tomto \u010dase m\u00f4\u017eu zamestnanci pracova\u0165 na \u010domko\u013evek! Niektor\u00e9 z najzn\u00e1mej\u0161\u00edch technologick\u00fdch projektov Dropboxu sa za\u010dali pr\u00e1ve po\u010das t\u00fdchto podujat\u00ed. Z tohto experimentu sme vyvodili z\u00e1very, \u017ee mypy vyzer\u00e1 s\u013eubne, hoci tento projekt zatia\u013e nebol pripraven\u00fd na \u0161irok\u00e9 pou\u017eitie.<\/p>\n<p>V tom \u010dase bola vo vzduchu my\u0161lienka na \u0161tandardiz\u00e1ciu syst\u00e9mov vyd\u00e1vania odpor\u00fa\u010dan\u00ed o typoch Pythonu. Ako som u\u017e spomenul, u\u017e od Pythonu 3.0 bolo mo\u017en\u00e9 pou\u017e\u00edva\u0165 anot\u00e1cie typov pre funkcie, ale to boli len n\u00e1hodn\u00e9 v\u00fdrazy, bez ur\u010den\u00e9ho syntaxe a s\u00e9mantiky. Po\u010das vykon\u00e1vania programu sa tieto anot\u00e1cie v\u00e4\u010d\u0161inou len ignorovali. Po Hack Weeku sme za\u010dali pracova\u0165 na \u0161tandardiz\u00e1cii s\u00e9mantiky. T\u00e1to pr\u00e1ca viedla k vzniku <noindex><a rel=\"nofollow\" href=\"https:\/\/www.python.org\/dev\/peps\/pep-0484\/\">PEP 484<\/a><\/noindex> (na tomto dokumente sa spolupodie\u013eali Guido van Rossum, Luk\u00e1\u0161 Langa a ja).<\/p>\n<p>Na\u0161e motiv\u00e1cie mohli by\u0165 posudzovan\u00e9 z dvoch perspekt\u00edv. Po prv\u00e9, d\u00fafali sme, \u017ee cel\u00e1 ekosyst\u00e9m Pythonu by mohol prija\u0165 spolo\u010dn\u00fd pr\u00edstup k pou\u017e\u00edvaniu odpor\u00fa\u010dan\u00ed typov (type hints - term\u00edn, ktor\u00fd sa v Python pou\u017e\u00edva ako ekvivalent \u201eanot\u00e1ci\u00ed typov\u201c). To by, vo svetle mo\u017en\u00fdch riz\u00edk, bolo lep\u0161ie ne\u017e pou\u017e\u00edvanie mno\u017estva vz\u00e1jomne nekompatibiln\u00fdch pr\u00edstupov. Po druh\u00e9, chceli sme otvorene diskutova\u0165 o mechanizmoch anotovania typov s mno\u017estvom predstavite\u013eov Python komunity. \u010ciasto\u010dne bolo toto \u017eelanie motivovan\u00e9 t\u00fdm, \u017ee sme nechceli vyzera\u0165 ako \u201eodpadl\u00edci\u201c od z\u00e1kladn\u00fdch my\u0161lienok jazyka v o\u010diach \u0161irokej verejnosti Python program\u00e1torov. Ide o dynamicky typizovan\u00fd jazyk, zn\u00e1my \u201eka\u010dacou typiz\u00e1ciou\u201c. V komunite bol zo za\u010diatku nevyhnutne zaujat\u00fd postoj k my\u0161lienke statickej typiz\u00e1cie. Ale tento postoj sa nakoniec oslaboval - po tom, \u010do sa uk\u00e1zalo, \u017ee zavedenie statickej typiz\u00e1cie nie je pl\u00e1novan\u00e9 ako povinn\u00e9 (a po tom, \u010do si \u013eudia uvedomili, \u017ee je skuto\u010dne u\u017eito\u010dn\u00e1).<\/p>\n<p>Prijat\u00fd syntax typov\u00fdch n\u00e1poved bol nakoniec ve\u013emi podobn\u00fd tomu, ktor\u00fd vtedy podporoval mypy. Dokument PEP 484 bol vydan\u00fd spolu s Python 3.5 v roku 2015. Python u\u017e nebol jazykom, ktor\u00fd podporoval len dynamick\u00fa typiz\u00e1ciu. R\u00e1d nad t\u00fdmto udal\u00edm rozm\u00fd\u0161\u013eam ako o v\u00fdznamnom m\u00ed\u013eniku v hist\u00f3rii Pythonu.<\/p>\n<h2>Za\u010diatok migr\u00e1cie<\/h2>\n<p>\nNa konci roka 2015 bola v Dropboxe vytvoren\u00e1 troj\u010dlenn\u00e1 t\u00edm pre pr\u00e1cu na mypy. Tvorili ho Guido van Rossum, Greg Price a David Fisher. Od tohto okamihu sa situ\u00e1cia za\u010dala rozv\u00edja\u0165 ve\u013emi r\u00fdchlo. Prv\u00fdm probl\u00e9mom na ceste rastu mypy bola v\u00fdkonnos\u0165. Ako som u\u017e nazna\u010dil vy\u0161\u0161ie, v rann\u00fdch f\u00e1zach v\u00fdvoja projektu som uva\u017eoval o presunut\u00ed implement\u00e1cie mypy do jazyka C, ale t\u00e1to my\u0161lienka bola zatia\u013e z programu vy\u010dlenen\u00e1. Uviazli sme na tom, \u017ee syst\u00e9m be\u017eal na interpreteri CPython, ktor\u00fd neprekvapil dostato\u010dnou r\u00fdchlos\u0165ou pre n\u00e1stroje ak\u00fdm je mypy. (Projekt PyPy, alternat\u00edvna implement\u00e1cia Pythonu s JIT kompil\u00e1torom, n\u00e1m tie\u017e pr\u00edli\u0161 nepomohol.)<\/p>\n<p>Na\u0161\u0165astie n\u00e1m prich\u00e1dzali na pomoc niektor\u00e9 algoritmick\u00e9 vylep\u0161enia. Prv\u00fdm siln\u00fdm \"zr\u00fdch\u013eova\u010dom\" bola implement\u00e1cia inkrement\u00e1lnych kontrol. My\u0161lienka tohto vylep\u0161enia bola jednoduch\u00e1: ak sa v\u0161etky z\u00e1vislosti modulu od posledn\u00e9ho spustenia mypy nezmenili, m\u00f4\u017eeme pri pr\u00e1ci so z\u00e1vislos\u0165ami pou\u017ei\u0165 \u00fadaje, ktor\u00e9 boli ulo\u017een\u00e9 po\u010das predch\u00e1dzaj\u00facej rel\u00e1cie. Museli sme len vykona\u0165 kontrolu typov v zmenen\u00fdch s\u00faboroch a v t\u00fdch s\u00faboroch, ktor\u00e9 od nich z\u00e1viseli. Mypy i\u0161iel dokonca o krok \u010falej: ak sa vonkaj\u0161\u00ed rozhranie modulu nezmenilo \u2014 mypy predpokladal, \u017ee in\u00e9 moduly, ktor\u00e9 tento modul importuj\u00fa, nie je potrebn\u00e9 kontrolova\u0165 znovu.<\/p>\n<p>Inkrement\u00e1lna kontrola n\u00e1m ve\u013emi pomohla pri anotovan\u00ed ve\u013ek\u00fdch objemov existuj\u00faceho k\u00f3du. Ide o to, \u017ee tento proces zvy\u010dajne zah\u0155\u0148a mno\u017estvo iterat\u00edvnych spusten\u00ed mypy, preto\u017ee anot\u00e1cie s\u00fa postupne prid\u00e1van\u00e9 do k\u00f3du a postupne vylep\u0161ovan\u00e9. Prv\u00e9 spustenie mypy bolo st\u00e1le ve\u013emi pomal\u00e9, preto\u017ee pri jeho vykon\u00e1van\u00ed bolo potrebn\u00e9 overi\u0165 mno\u017estvo z\u00e1vislost\u00ed. Preto sme, v snahe zlep\u0161i\u0165 situ\u00e1ciu, implementovali mechanizmus vzdialen\u00e9ho caching-u. Ak mypy zist\u00ed, \u017ee lok\u00e1lny cache je pravdepodobne zastaran\u00fd, na\u010d\u00edta aktu\u00e1lny snapshot cache pre cel\u00fa k\u00f3dov\u00fa z\u00e1klad\u0148u z centralizovan\u00e9ho repozit\u00e1ra. Potom vykon\u00e1va inkrement\u00e1lnu kontrolu s pou\u017eit\u00edm tohto snapshotu. To n\u00e1s posunulo o \u010fal\u0161\u00ed v\u00fdznamn\u00fd krok na ceste k zv\u00fd\u0161eniu v\u00fdkonu mypy.<\/p>\n<p>Bol to \u010das r\u00fdchlej a prirodzenej implement\u00e1cie syst\u00e9mu kontroly typov v Dropboxe. Na konci roka 2016 sme mali u\u017e asi 420 000 riadkov Python k\u00f3du s anot\u00e1ciami typov. Mnoh\u00ed pou\u017e\u00edvatelia sa nad\u0161ene postavili k kontrole typov. V Dropboxe mypy vyu\u017e\u00edvalo \u010doraz viac t\u00edmov v\u00fdvoj\u00e1rov.<\/p>\n<p>V\u0161etko vtedy vyzeralo dobre, ale e\u0161te n\u00e1s \u010dakalo ve\u013ea pr\u00e1ce. Za\u010dali sme vykon\u00e1va\u0165 pravideln\u00e9 intern\u00e9 prieskumy pou\u017e\u00edvate\u013eov, aby sme identifikovali problematick\u00e9 oblasti projektu a pochopili, ak\u00e9 ot\u00e1zky je potrebn\u00e9 rie\u0161i\u0165 ako prv\u00e9 (t\u00e1to prax sa v spolo\u010dnosti pou\u017e\u00edva aj dnes). Ako sa uk\u00e1zalo, najd\u00f4le\u017eitej\u0161ie boli dve \u00falohy. Prv\u00e1 \u2014 potrebovali sme v\u00e4\u010d\u0161ie pokrytie k\u00f3du typmi, druh\u00e1 \u2014 mypy musel pracova\u0165 r\u00fdchlej\u0161ie. Bolo \u00faplne jasn\u00e9, \u017ee na\u0161a pr\u00e1ca na zr\u00fdchlen\u00ed mypy a jeho implement\u00e1cii do projektov spolo\u010dnosti bola e\u0161te \u010faleko od dokon\u010denia. Plne sme si uvedomovali d\u00f4le\u017eitos\u0165 t\u00fdchto dvoch \u00faloh a pustili sme sa do ich rie\u0161enia.<\/p>\n<h2>Viac v\u00fdkonu!<\/h2>\n<p>\nInkrement\u00e1lne kontroly zr\u00fdchlili mypy, ale tento n\u00e1stroj st\u00e1le nebol dos\u0165 r\u00fdchly. Mnoh\u00e9 inkrement\u00e1lne kontroly trvali okolo min\u00faty. Pr\u00ed\u010dinou bola cyklick\u00e1 import\u00e1cia. To pravdepodobne neprekvap\u00ed nikoho, kto pracoval s ve\u013ek\u00fdmi k\u00f3dov\u00fdmi z\u00e1kladmi nap\u00edsan\u00fdmi v Pythone. Mali sme sady zo stoviek modulov, z ktor\u00fdch ka\u017ed\u00fd nepriamo importoval v\u0161etky ostatn\u00e9. Ak bol ak\u00fdko\u013evek s\u00fabor v cykle importov zmenen\u00fd, mypy musel spracova\u0165 v\u0161etky s\u00fabory, ktor\u00e9 patrili do tohto cyklu, a \u010dasto aj ak\u00e9ko\u013evek moduly, ktor\u00e9 importovali moduly z tohto cyklu. Jedn\u00fdm z tak\u00fdchto cyklov bol zn\u00e1my \"klb z\u00e1vislost\u00ed\", ktor\u00fd sp\u00f4sobil mno\u017estvo probl\u00e9mov v Dropboxe. Raz t\u00e1to \u0161trukt\u00fara obsahovala nieko\u013eko stoviek modulov, pri\u010dom bola importovan\u00e1, priamo alebo nepriamo, mno\u017estvom testov a pou\u017e\u00edvala sa aj v produk\u010dnom k\u00f3de.<\/p>\n<p>Zva\u017eovali sme mo\u017enos\u0165 \"rozuzlenia\" cyklick\u00fdch z\u00e1vislost\u00ed, ale nemali sme zdroje na to, aby sme to uskuto\u010dnili. Bolo tam pr\u00edli\u0161 ve\u013ea k\u00f3du, s ktor\u00fdm sme neboli obozn\u00e1men\u00ed. Nakoniec sme sa dostali k alternat\u00edvnemu pr\u00edstupu. Rozhodli sme sa, \u017ee mypy bude r\u00fdchlo fungova\u0165 aj pri existencii \"klbov z\u00e1vislost\u00ed\". Tento cie\u013e sme dosiahli pomocou d\u00e9mona mypy. Demon je serverov\u00fd proces, ktor\u00fd realizuje dve zauj\u00edmav\u00e9 funkcie. Po prv\u00e9 \u2013 uchov\u00e1va v pam\u00e4ti inform\u00e1cie o celej k\u00f3dovej b\u00e1ze. To znamen\u00e1, \u017ee pri ka\u017edom spusten\u00ed mypy nie je potrebn\u00e9 na\u010d\u00edtava\u0165 cachovan\u00e9 \u00fadaje t\u00fdkaj\u00face sa tis\u00edcov importovan\u00fdch z\u00e1vislost\u00ed. Po druh\u00e9 \u2013 starostlivo, na \u00farovni drobn\u00fdch \u0161truktur\u00e1lnych jednotiek, analyzuje z\u00e1vislosti medzi funkciami a in\u00fdmi entitami. Napr\u00edklad, ak funkcia <code>foo<\/code> vyvol\u00e1va funkciu <code>bar<\/code>, potom existuje z\u00e1vislos\u0165 <code>foo<\/code> od <code>bar<\/code>. Ke\u010f sa s\u00fabor zmen\u00ed \u2013 d\u00e9mon najprv, v izol\u00e1cii, spracov\u00e1va iba zmenen\u00fd s\u00fabor. Potom sa pozrie na zmeny tohto s\u00faboru, vidite\u013en\u00e9 navonok, ako s\u00fa zmenen\u00e9 podpisy funkci\u00ed. Demon pou\u017e\u00edva podrobn\u00e9 inform\u00e1cie o importoch iba na overenie t\u00fdch funkci\u00ed, ktor\u00e9 naozaj pou\u017e\u00edvaj\u00fa zmenen\u00fa funkciu. Zvy\u010dajne je pri takomto pr\u00edstupe potrebn\u00e9 overi\u0165 len ve\u013emi m\u00e1lo funkci\u00ed.<\/p>\n<p>Realiz\u00e1cia v\u0161etk\u00e9ho tohto nebola jednoduch\u00e1 \u00faloha, preto\u017ee p\u00f4vodn\u00e1 implement\u00e1cia mypy bola ve\u013emi zameran\u00e1 na spracovanie jedn\u00e9ho s\u00faboru naraz. Museli sme \u010deli\u0165 mnoh\u00fdm hrani\u010dn\u00fdm situ\u00e1ci\u00e1m, ktor\u00fdch vznik si vy\u017eadoval opakovan\u00e9 kontroly v pr\u00edpadoch, ke\u010f sa v k\u00f3de nie\u010do zmenilo. Napr\u00edklad to nast\u00e1va, ke\u010f triede pridelia nov\u00fa z\u00e1kladn\u00fa triedu. Po tom, \u010do sme dosiahli, \u010do sme chceli, sme dok\u00e1zali zn\u00ed\u017ei\u0165 \u010das vykon\u00e1vania v\u00e4\u010d\u0161iny inkrement\u00e1lnych kontrol na nieko\u013eko sek\u00fand. Pova\u017eovali sme to za ve\u013ek\u00e9 v\u00ed\u0165azstvo.<\/p>\n<h2>E\u0161te viac v\u00fdkonu!<\/h2>\n<p>\nSpolu s dia\u013ekov\u00fdm cachingom, o ktorom som hovoril vy\u0161\u0161ie, d\u00e9mon mypy prakticky \u00faplne vyrie\u0161il probl\u00e9my, ktor\u00e9 vznikaj\u00fa, ke\u010f program\u00e1tor \u010dasto sp\u00fa\u0161\u0165a kontrolu typov, pri\u010dom rob\u00ed zmeny v malom po\u010dte s\u00faborov. Av\u0161ak v\u00fdkon syst\u00e9mu v najmenej priaznivom variante jeho pou\u017eitia bol st\u00e1le \u010faleko od optim\u00e1lneho. \u010cist\u00e9 spustenie mypy mohlo trva\u0165 viac ne\u017e 15 min\u00fat. A to bolo ove\u013ea viac, ne\u017e by n\u00e1m vyhovovalo. Ka\u017ed\u00fd t\u00fd\u017ede\u0148 sa situ\u00e1cia zhor\u0161ovala, preto\u017ee program\u00e1tori pokra\u010dovali v p\u00edsan\u00ed nov\u00e9ho k\u00f3du a prid\u00e1van\u00ed anot\u00e1ci\u00ed k existuj\u00facemu k\u00f3du. Na\u0161i pou\u017e\u00edvatelia st\u00e1le t\u00fa\u017eili po v\u00e4\u010d\u0161ej v\u00fdkonnosti, a my sme boli ochotn\u00ed im vyhovie\u0165.<\/p>\n<p>Rozhodli sme sa vr\u00e1ti\u0165 k jednej z na\u0161ich skor\u0161\u00edch my\u0161lienok t\u00fdkaj\u00facich sa mypy. A s\u00edce k transform\u00e1cii Python k\u00f3du na C k\u00f3d. Experimenty s Cython (\u010do je syst\u00e9m, ktor\u00fd umo\u017e\u0148uje preklada\u0165 k\u00f3d nap\u00edsan\u00fd v Pythone do C k\u00f3du) n\u00e1m nepriniesli \u017eiadne vidite\u013en\u00e9 zr\u00fdchlenie, a preto sme sa rozhodli o\u017eivi\u0165 my\u0161lienku p\u00edsania vlastn\u00e9ho kompil\u00e1tora. Ke\u010f\u017ee k\u00f3dov\u00e1 z\u00e1klad\u0148a mypy (nap\u00edsan\u00e1 v Pythone) u\u017e obsahovala v\u0161etky potrebn\u00e9 typov\u00e9 anot\u00e1cie, zdalo sa n\u00e1m, \u017ee stoj\u00ed za to pok\u00fasi\u0165 sa vyu\u017ei\u0165 tieto anot\u00e1cie na zr\u00fdchlenie pr\u00e1ce syst\u00e9mu. R\u00fdchlo som vytvoril prototyp na overenie tejto my\u0161lienky, ktor\u00fd uk\u00e1zal na r\u00f4znych mikrobenchmarkoch viac ako 10-n\u00e1sobn\u00fd n\u00e1rast v\u00fdkonu. Na\u0161a my\u0161lienka spo\u010d\u00edvala v tom, aby sme prekladali Python moduly na C moduly pomocou Cython a premenili typov\u00e9 anot\u00e1cie na typov\u00e9 kontroly vykon\u00e1van\u00e9 po\u010das behu programu (zvy\u010dajne sa typov\u00e9 anot\u00e1cie ignoruj\u00fa po\u010das behu programov a pou\u017e\u00edvaj\u00fa sa len syst\u00e9mami na kontrolu typov). V skuto\u010dnosti sme pl\u00e1novali prenies\u0165 implement\u00e1ciu mypy z Pythonu do jazyka, ktor\u00fd bol vytvoren\u00fd staticky typovan\u00fdm sp\u00f4sobom, ktor\u00fd by vyzeral (a vo v\u00e4\u010d\u0161ine by aj fungoval) presne ako Python. (Tento druh medzi-jazykovej migr\u00e1cie sa stal akousi trad\u00edciou projektu mypy. P\u00f4vodn\u00e1 implement\u00e1cia mypy bola nap\u00edsan\u00e1 v Alore, potom bol syntaktick\u00fd hybrid Java a Python).<\/p>\n<p>Zameranie na API roz\u0161\u00edren\u00ed CPython bolo k\u013e\u00fa\u010dom k tomu, aby sme nestratili mo\u017enosti pri spr\u00e1ve projektu. Nemuseli sme implementova\u0165 virtu\u00e1lny stroj alebo ak\u00e9ko\u013evek kni\u017enice, ktor\u00e9 mypy potreboval. Okrem toho by n\u00e1m st\u00e1le bola k dispoz\u00edcii cel\u00e1 ekosyst\u00e9m Pythonu, v\u0161etky n\u00e1stroje (ako pytest). To znamenalo, \u017ee sme mohli pokra\u010dova\u0165 v pou\u017e\u00edvan\u00ed interpretovan\u00e9ho Python k\u00f3du po\u010das v\u00fdvoja, \u010do n\u00e1m umo\u017enilo pokra\u010dova\u0165 v pr\u00e1ci s ve\u013emi r\u00fdchlym sch\u00e9mirakom zmien v k\u00f3de a jeho testovania, a nie \u010daka\u0165 na kompil\u00e1ciu k\u00f3du. Vyzeralo to tak, \u017ee sa n\u00e1m skvele dar\u00ed, keby sme to tak povedali, sedie\u0165 na dvoch stoli\u010dk\u00e1ch, a to sa n\u00e1m p\u00e1\u010dilo.<\/p>\n<p>Kompil\u00e1tor, ktor\u00fd sme nazvali mypyc (ke\u010f\u017ee ako frontend pou\u017e\u00edva na anal\u00fdzu typov mypy), sa uk\u00e1zal by\u0165 ve\u013emi \u00faspe\u0161n\u00fdm projektom. Celkovo sme dosiahli pribli\u017ene 4-n\u00e1sobn\u00e9 ur\u00fdchlenie \u010dast\u00fdch spusten\u00ed mypy bez pou\u017eitia cache. V\u00fdvoj jadra projektu mypyc trval malej skupine, do ktorej patrili Michael Sullivan, Ivan Levkivsky, Hugh Han a ja, pribli\u017ene 4 kalend\u00e1rne mesiace. Tento objem pr\u00e1ce bol ove\u013ea men\u0161\u00ed, ako by bol potrebn\u00fd na prepis mypy, napr\u00edklad do C++ alebo Go. A zmien v projekte sme museli vykona\u0165 ove\u013ea menej, ne\u017e keby sme ho prepisovali do in\u00e9ho jazyka. Verili sme tie\u017e, \u017ee dok\u00e1\u017eeme mypyc vylep\u0161i\u0165 do takej \u00farovne, aby ho mohli pou\u017e\u00edva\u0165 aj in\u00ed program\u00e1tori z Dropboxu na kompil\u00e1ciu a ur\u00fdchlenie svojho k\u00f3du.<\/p>\n<p>Na dosiahnutie podobnej \u00farovne v\u00fdkonu sme museli aplikova\u0165 niektor\u00e9 zauj\u00edmav\u00e9 in\u017einierske rie\u0161enia. Takto kompil\u00e1tor m\u00f4\u017ee ur\u00fdchli\u0165 vykon\u00e1vanie mnoh\u00fdch oper\u00e1ci\u00ed pou\u017eit\u00edm r\u00fdchlych n\u00edzko\u00farov\u0148ov\u00fdch kon\u0161trukci\u00ed C. Napr\u00edklad, volanie skompilovanej funkcie sa prelo\u017e\u00ed na volanie C-funkcie. A tak\u00e9to volanie sa vykon\u00e1va ove\u013ea r\u00fdchlej\u0161ie ako volanie interpretovanej funkcie. Niektor\u00e9 oper\u00e1cie, ako vyh\u013ead\u00e1vanie v slovn\u00edkoch, sa st\u00e1le museli riadi\u0165 be\u017en\u00fdmi volaniami C-API z CPythonu, ktor\u00e9 po kompil\u00e1cii boli len o nie\u010do r\u00fdchlej\u0161ie. Podarilo sa n\u00e1m zbavi\u0165 dodato\u010dnej z\u00e1\u0165a\u017ee na syst\u00e9m, ktor\u00fa vytv\u00e1ralo interpretovanie, ale to v tomto pr\u00edpade prinieslo len mal\u00fd zisk z h\u013eadiska v\u00fdkonu.<\/p>\n<p>Na odhalenie najbe\u017enej\u0161\u00edch \u201epomal\u00fdch\u201c oper\u00e1ci\u00ed sme vykonali profilovanie k\u00f3du. S pou\u017eit\u00edm z\u00edskan\u00fdch \u00fadajov sme sa pok\u00fasili bu\u010f tak \u201evyladi\u0165\u201c mypyc, aby generoval r\u00fdchlej\u0161\u00ed C-k\u00f3d pre podobn\u00e9 oper\u00e1cie, alebo prepracova\u0165 pr\u00edslu\u0161n\u00fd Python k\u00f3d pomocou r\u00fdchlej\u0161\u00edch oper\u00e1ci\u00ed (niekedy sme jednoducho nemali dostato\u010dne jednoduch\u00e9 rie\u0161enie pre dan\u00fd probl\u00e9m). Prepisovanie Python k\u00f3du sa \u010dasto uk\u00e1zalo ako jednoduch\u0161ie rie\u0161enie probl\u00e9mu ako implement\u00e1cia automatick\u00e9ho vykon\u00e1vania tej istej transform\u00e1cie v kompil\u00e1tore. Z dlhodob\u00e9ho h\u013eadiska sme chceli automatizova\u0165 mnoh\u00e9 z t\u00fdchto transform\u00e1ci\u00ed, ale v tej chv\u00edli sme sa zameriavali na to, aby sme s minim\u00e1lnym \u00fasil\u00edm zr\u00fdchlili mypy. A na ceste k tomuto cie\u013eu sme urobili nieko\u013eko \u00fastupkov.<\/p>\n<p>Pokra\u010dov\u00e1n\u00ed n\u00e1sleduje\u2026<\/p>\n<p><b>V\u00e1\u017een\u00ed \u010ditatelia!<\/b> Ak\u00e9 dojmy vo v\u00e1s vyvolal projekt mypy v \u010dase, ke\u010f ste sa o \u0148om dozvedeli?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Cesta k overeniu typov 4 mili\u00f3nov riadkov k\u00f3du v Pythone. \u010cas\u0165 2\" 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=\"Cesta k overeniu typov 4 mili\u00f3nov riadkov k\u00f3du v Pythone. \u010cas\u0165 2\" src=\"\/wp-content\/uploads\/2019\/09\/263173dd3ab487da330ff9063e3c180e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Zdroj: <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.5 - 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\/sk\/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.5\" \/>\n\t\t<meta property=\"og:locale\" content=\"sk_SK\" \/>\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\/sk\/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\udd47Cesta k overovaniu typov 4 mili\u00f3nov riadkov Python k\u00f3du. \u010cas\u0165 2 | ProHoster","description":"Dnes zverej\u0148ujeme druh\u00fa \u010das\u0165 prekladu materi\u00e1lu o tom, ako v Dropboxe organizovali kontrolu typov nieko\u013ek\u00fdch mili\u00f3nov riadkov Python k\u00f3du.","canonical_url":"https:\/\/prohoster.info\/sk\/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":"sk_SK","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\/sk\/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\/sk\/wp-json\/wp\/v2\/posts\/38479","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/comments?post=38479"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts\/38479\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media\/28879"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media?parent=38479"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/categories?post=38479"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/tags?post=38479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}