{"id":38649,"date":"2019-10-31T22:25:04","date_gmt":"2019-10-31T19:25:04","guid":{"rendered":"https:\/\/prohoster.info\/blog\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\/"},"modified":"2019-10-31T22:25:04","modified_gmt":"2019-10-31T19:25:04","slug":"put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","title":{"rendered":"Cesta k overeniu typov 4 mili\u00f3nov riadkov Python k\u00f3du. \u010cas\u0165 3","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Predstavujeme v\u00e1m tretiu \u010das\u0165 prekladu materi\u00e1lu o ceste, ktor\u00fa pre\u0161la spolo\u010dnos\u0165 Dropbox pri zav\u00e1dzan\u00ed syst\u00e9mu overovania typov Python k\u00f3du.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\"><img decoding=\"async\" alt=\"Cesta k overeniu typov 4 mili\u00f3nov riadkov Python k\u00f3du. \u010cas\u0165 3\" src=\"\/wp-content\/uploads\/2019\/10\/757669265e870de604388c66adef814d.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u2192 Predch\u00e1dzaj\u00face \u010dasti: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468233\/\">prv\u00fd<\/a><\/noindex> a <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\">druh\u00e1<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Dosiahnutie 4 mili\u00f3nov riadkov typizovan\u00e9ho k\u00f3du<\/h2>\n<p>\n\u010eal\u0161ou d\u00f4le\u017eitou \u00falohou (toto bola druh\u00e1 najpopul\u00e1rnej\u0161ia ot\u00e1zka, ktor\u00e1 znepokojovala t\u00fdch, ktor\u00ed sa z\u00fa\u010dastnili intern\u00fdch prieskumov) bolo zv\u00fd\u0161i\u0165 objem k\u00f3du v Dropboxe pokryt\u00e9ho overen\u00edm typov. Vysk\u00fa\u0161ali sme nieko\u013eko pr\u00edstupov na rie\u0161enie tejto \u00falohy \u2014 od prirodzen\u00e9ho rastu objemu typizovanej k\u00f3dovej z\u00e1kladne po zameranie \u00fasilia \u010dlenov t\u00edmu mypy na statickom a dynamickom automatizovanom odvoden\u00ed typov. Nakoniec sa vytvoril dojem, \u017ee neexistuje jednoduch\u00e1 v\u00ed\u0165azn\u00e1 strat\u00e9gia, ale podarilo sa n\u00e1m dosiahnu\u0165 r\u00fdchly rast objemu anotovan\u00e9ho k\u00f3du kombinovan\u00edm viacer\u00fdch pr\u00edstupov.<\/p>\n<p>V\u00fdsledkom je, \u017ee v na\u0161om najv\u00e4\u010d\u0161om Python repozit\u00e1ri (s backend k\u00f3dom) dosiahlo mno\u017estvo riadkov anotovan\u00e9ho k\u00f3du takmer 4 mili\u00f3ny. Pr\u00e1ca na statickej typiz\u00e1cii k\u00f3du bola vykonan\u00e1 pribli\u017ene za tri roky. Mypy teraz podporuje r\u00f4zne druhy spr\u00e1v o pokryt\u00ed k\u00f3dom typmi, ktor\u00e9 u\u013eah\u010duj\u00fa sledovanie priebehu typiz\u00e1cie. Konkr\u00e9tne m\u00f4\u017eeme vytv\u00e1ra\u0165 spr\u00e1vy pre k\u00f3d s neur\u010ditos\u0165ami v typoch, s tak\u00fdmi napr\u00edklad ako explicitn\u00e9 pou\u017eitie typu <code>Any<\/code> v anot\u00e1ci\u00e1ch, ktor\u00e9 nemo\u017eno overi\u0165, alebo s tak\u00fdmi, ako je import extern\u00fdch kni\u017en\u00edc, v ktor\u00fdch nie s\u00fa anot\u00e1cie typov. V r\u00e1mci projektu zameran\u00e9ho na zv\u00fd\u0161enie presnosti overovania typov v Dropboxe sme prispevali k zlep\u0161eniu defin\u00edci\u00ed typov (tzv. stub s\u00faborov) pre niektor\u00e9 popul\u00e1rne open-source kni\u017enice v centralizovanom Python repozit\u00e1ri <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/python\/typeshed\">typeshed<\/a><\/noindex>.<\/p>\n<p>Implementovali sme (a \u0161tandardizovali v nasleduj\u00facich PEP) nov\u00e9 funk\u010dnosti syst\u00e9mu typov, ktor\u00e9 umo\u017e\u0148uj\u00fa pou\u017e\u00edva\u0165 presnej\u0161ie typy pre niektor\u00e9 \u0161pecifick\u00e9 Python vzory. V\u00fdznamn\u00fdm pr\u00edkladom toho je <code>TypeDict<\/code>, ktor\u00fd poskytuje typy pre JSON podoben\u00e9 slovn\u00edky, ktor\u00e9 maj\u00fa fixn\u00fa sadu re\u0165azcov\u00fdch k\u013e\u00fa\u010dov, z ktor\u00fdch ka\u017ed\u00fd m\u00e1 hodnotu vlastn\u00e9ho typu. Pokra\u010dujeme v roz\u0161irovan\u00ed syst\u00e9mu typov. Pravdepodobne na\u0161\u00edm \u010fal\u0161\u00edm krokom bude zlep\u0161enie podpory funkci\u00ed Pythonu pre pr\u00e1cu s \u010d\u00edslami.<\/p>\n<p><img decoding=\"async\" alt=\"Cesta k overeniu typov 4 mili\u00f3nov riadkov Python k\u00f3du. \u010cas\u0165 3\" src=\"\/wp-content\/uploads\/2019\/10\/297b9e823141d6cb0d2f19f9a78a1153.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Po\u010det riadkov anotovan\u00e9ho k\u00f3du: server<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Cesta k overeniu typov 4 mili\u00f3nov riadkov Python k\u00f3du. \u010cas\u0165 3\" src=\"\/wp-content\/uploads\/2019\/10\/c183a9227e51d847bfdb2b8f6153684f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Po\u010det riadkov anotovan\u00e9ho k\u00f3du: klient<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Cesta k overeniu typov 4 mili\u00f3nov riadkov Python k\u00f3du. \u010cas\u0165 3\" src=\"\/wp-content\/uploads\/2019\/10\/0a8b936fa454a34c09a9c6a2694485c9.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Celkov\u00fd po\u010det riadkov anotovan\u00e9ho k\u00f3du<\/i><\/p>\n<p>Tu je preh\u013ead hlavn\u00fdch funkci\u00ed akci\u00ed, ktor\u00e9 sme vykonali na zv\u00fd\u0161enie objemu anotovan\u00e9ho k\u00f3du v Dropboxe:<\/p>\n<p>Pr\u00edsnos\u0165 anotovania. Postupne sme zvy\u0161ovali po\u017eiadavky na pr\u00edsnos\u0165 anotovania nov\u00e9ho k\u00f3du. Za\u010dali sme odpor\u00fa\u010daniami lintra, ktor\u00e9 navrhovali prid\u00e1va\u0165 anot\u00e1cie do s\u00faborov, v ktor\u00fdch u\u017e existuj\u00fa niektor\u00e9 anot\u00e1cie. Teraz po\u017eadujeme pr\u00edtomnos\u0165 typov\u00fdch anot\u00e1ci\u00ed v nov\u00fdch Python s\u00faboroch a vo v\u00e4\u010d\u0161ine existuj\u00facich s\u00faborov.<\/p>\n<p>Spr\u00e1vy o typovan\u00ed. Ka\u017ed\u00fd t\u00fd\u017ede\u0148 posielame t\u00edmom spr\u00e1vy o \u00farovni typovania ich k\u00f3du a poskytujeme rady, \u010do by mali prioritne anotova\u0165.<\/p>\n<p>Populariz\u00e1cia mypy. Informujeme o mypy na r\u00f4znych podujatiach a komunikujeme s t\u00edmami, aby sme im pomohli za\u010da\u0165 pou\u017e\u00edva\u0165 typov\u00e9 anot\u00e1cie.<\/p>\n<p>Prieskumy. PPeriodicky vykon\u00e1vame prieskumy pou\u017e\u00edvate\u013eov na identifik\u00e1ciu hlavn\u00fdch probl\u00e9mov. Sme pripraven\u00ed \u00eds\u0165 dos\u0165 \u010faleko v rie\u0161en\u00ed t\u00fdchto probl\u00e9mov (a\u017e po vytvorenie nov\u00e9ho jazyka pre ur\u00fdchlenie mypy!).<\/p>\n<p>V\u00fdkon. V\u00fdrazne sme zlep\u0161ili v\u00fdkon mypy v\u010faka pou\u017e\u00edvaniu d\u00e9mona a mypyc. To sa urobilo, aby sa zmiernili \u0165a\u017ekosti spojen\u00e9 s anotovan\u00edm a aby sme mohli pracova\u0165 s ve\u013ek\u00fdmi objemami k\u00f3du.<\/p>\n<p>Integr\u00e1cia s editormi. Vytvorili sme prostriedky na podporu sp\u00fa\u0161\u0165ania mypy v editore, ktor\u00e9 s\u00fa popul\u00e1rne v Dropboxe. Tieto zah\u0155\u0148aj\u00fa PyCharm, Vim a VS Code. To v\u00fdznamne zjednodu\u0161ilo proces vykon\u00e1vania pr\u00e1c na anotovan\u00ed k\u00f3du a kontrole jeho funk\u010dnosti. Tak\u00e9to akcie s\u00fa zvy\u010dajne charakteristick\u00e9 pri anotovan\u00ed existuj\u00faceho k\u00f3du.<\/p>\n<p>Statick\u00e1 anal\u00fdza. Vytvorili sme n\u00e1stroj na v\u00fdstup funk\u010dn\u00fdch podpisov pomocou prostriedkov statickej anal\u00fdzy. Tento n\u00e1stroj m\u00f4\u017ee fungova\u0165 len v relat\u00edvne jednoduch\u00fdch situ\u00e1ci\u00e1ch, ale pomohol n\u00e1m bez v\u00e4\u010d\u0161\u00edch \u00fasilia zv\u00fd\u0161i\u0165 pokrytie k\u00f3du typmi.<\/p>\n<p>Podpora extern\u00fdch kni\u017en\u00edc. Vo viacer\u00fdch na\u0161ich projektoch pou\u017e\u00edvame s\u00fabor n\u00e1strojov SQLAlchemy. V \u0148om vyu\u017e\u00edvame dynamick\u00e9 mo\u017enosti Pythona, ktor\u00e9 typy PEP 484 nedok\u00e1\u017eu priamo modelova\u0165. V s\u00falade s PEP 561 sme vytvorili zodpovedaj\u00faci stub s\u00fabor a nap\u00edsali plugin pre mypy (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dropbox\/sqlalchemy-stubs\">open-source<\/a><\/noindex>), ktor\u00fd zlep\u0161uje podporu SQLAlchemy.<\/p>\n<h2>Probl\u00e9my, s ktor\u00fdmi sme sa stretli<\/h2>\n<p>\nCesta k 4 mili\u00f3nom riadkov typizovan\u00e9ho k\u00f3du n\u00e1m nepriniesla v\u017edy \u013eahkosti. Na tejto ceste sme sa stretli s nemal\u00fdmi jamami a urobili sme nieko\u013eko ch\u00fdb. Tu s\u00fa niektor\u00e9 z probl\u00e9mov, s ktor\u00fdmi sme sa stretli. D\u00fafame, \u017ee rozpr\u00e1vanie o nich pom\u00f4\u017ee in\u00fdm predch\u00e1dza\u0165 podobn\u00fdm probl\u00e9mom.<\/p>\n<p>Zme\u0161kan\u00e9 s\u00fabory. Za\u010d\u00ednali sme pr\u00e1cu len s kontrolou mal\u00e9ho objemu s\u00faborov. V\u0161etko, \u010do nepatrilo do tohto po\u010dtu s\u00faborov, nebolo kontrolovan\u00e9. S\u00fabory boli pridan\u00e9 do kontroln\u00e9ho zoznamu vtedy, ke\u010f sa v nich objavili prv\u00e9 anot\u00e1cie. Ak sa nie\u010do importovalo z modulu umiestnen\u00e9ho mimo oblasti kontroly, hovorili sme o pr\u00e1ci s hodnotami typu <code>Any<\/code>, ktor\u00e9 sa v\u00f4bec nekontrolovali. To viedlo k zna\u010dnej strate presnosti typiz\u00e1cie, najm\u00e4 v po\u010diato\u010dn\u00fdch f\u00e1zach migr\u00e1cie. Tento pr\u00edstup sa predsa len uk\u00e1zal by\u0165 prekvapivo \u00fa\u010dinn\u00fd, aj ke\u010f typickou situ\u00e1ciou bolo, \u017ee pridanie s\u00faborov do oblasti kontroly odhalilo probl\u00e9my v in\u00fdch \u010dastiach k\u00f3dovej b\u00e1zy. V najhor\u0161om pr\u00edpade, ke\u010f sa spojili dve izolovan\u00e9 oblasti k\u00f3du, v ktor\u00fdch boli typy u\u017e skontrolovan\u00e9 nez\u00e1visle, sa zistilo, \u017ee typy t\u00fdchto oblast\u00ed s\u00fa navz\u00e1jom nekompatibiln\u00e9. To viedlo k potrebnosti vnies\u0165 mnoho zmien do anot\u00e1ci\u00ed. Teraz, ke\u010f sa ohladne sp\u00e4tne, si uvedomujeme, \u017ee sme mali \u010do najsk\u00f4r prida\u0165 do oblasti kontroly typov mypy z\u00e1kladn\u00e9 kni\u017enicov\u00e9 moduly. To by na\u0161u pr\u00e1cu urobilo ove\u013ea predv\u00eddate\u013enej\u0161ou.<\/p>\n<p>Annot\u00e1cia star\u00e9ho k\u00f3du. Ke\u010f sme za\u010dali pracova\u0165, mali sme pribli\u017ene 4 mili\u00f3ny riadkov existuj\u00faceho Python k\u00f3du. Bolo jasn\u00e9, \u017ee anotovanie v\u0161etk\u00e9ho tohto k\u00f3du je \u00faloha, ktor\u00e1 nie je jednoduch\u00e1. Vytvorili sme n\u00e1stroj nazvan\u00fd PyAnnotate, ktor\u00fd dok\u00e1\u017ee zbiera\u0165 inform\u00e1cie o typoch po\u010das vykon\u00e1vania testov a vie prida\u0165 do k\u00f3du typov\u00e9 anot\u00e1cie na z\u00e1klade zozbieran\u00fdch inform\u00e1ci\u00ed. Av\u0161ak, najm\u00e4 \u0161irok\u00e9 zavedenie tohto n\u00e1stroja sme nezaznamenali. Zber inform\u00e1ci\u00ed o typoch bol pomal\u00fd, automaticky generovan\u00e9 anot\u00e1cie \u010dasto vy\u017eadovali mno\u017estvo ru\u010dn\u00fdch \u00faprav. Uva\u017eovali sme o automatickom spusten\u00ed tohto n\u00e1stroja pri ka\u017edej kontrole k\u00f3du alebo o tom, \u017ee zbierame inform\u00e1cie o typoch na z\u00e1klade anal\u00fdzy ur\u010dit\u00e9ho mal\u00e9ho objemu re\u00e1lnych sie\u0165ov\u00fdch po\u017eiadaviek, ale rozhodli sme sa to neurobi\u0165, preto\u017ee ktor\u00fdko\u013evek z t\u00fdchto pr\u00edstupov bol pr\u00edli\u0161 riskantn\u00fd.<\/p>\n<p>Na konci m\u00f4\u017eeme poznamena\u0165, \u017ee v\u00e4\u010d\u0161ina k\u00f3du bola ru\u010dne anotovan\u00e1 jeho vlastn\u00edkmi. My, aby sme nasmerovali tento proces spr\u00e1vnym smerom, pripravujeme spr\u00e1vy o obzvl\u00e1\u0161\u0165 d\u00f4le\u017eit\u00fdch moduloch a funkci\u00e1ch, ktor\u00e9 je potrebn\u00e9 anotova\u0165. Napr\u00edklad je d\u00f4le\u017eit\u00e9 vybavi\u0165 anot\u00e1ciami typov kni\u017eni\u010dn\u00fd modul, ktor\u00fd sa pou\u017e\u00edva na stovk\u00e1ch miest. Star\u00fd servis, ktor\u00fd nahr\u00e1dzaj\u00fa nov\u00fdm, u\u017e nie je tak\u00e9 d\u00f4le\u017eit\u00e9 anotova\u0165. Okrem toho experimentujeme s pou\u017eit\u00edm statickej anal\u00fdzy na generovanie anot\u00e1ci\u00ed typov pre star\u00fd k\u00f3d.<\/p>\n<p>Cyklick\u00e9 importy. Predch\u00e1dzaj\u00face som hovoril o cyklick\u00fdch importoch (o \"klbk\u00e1ch z\u00e1vislost\u00ed\"), ktor\u00fdch existencia s\u0165a\u017eovala zr\u00fdchlenie mypy. Museli sme tie\u017e tvrdo pracova\u0165 na tom, aby sme mypy vybavili podporou v\u0161etk\u00fdch druhov idiomov, ktor\u00fdch vznik sp\u00f4sobuj\u00fa tieto cyklick\u00e9 importy. Ned\u00e1vno sme dokon\u010dili ve\u013ek\u00fd projekt redesignu syst\u00e9mu, ktor\u00fd odstr\u00e1nil v\u00e4\u010d\u0161inu probl\u00e9mov mypy t\u00fdkaj\u00facich sa cyklick\u00fdch importov. Tieto probl\u00e9my v skuto\u010dnosti vznikli u\u017e v ran\u00fdch d\u0148och projektu, e\u0161te po\u010das Alore, u\u010debn\u00e9ho jazyka, na ktor\u00fd bol projekt mypy p\u00f4vodne orientovan\u00fd. Syntax Alore umo\u017e\u0148uje \u013eahko rie\u0161i\u0165 probl\u00e9my s cyklick\u00fdmi pr\u00edkazmi importu. Modern\u00fd mypy zdedil niektor\u00e9 obmedzenia zo svojej ran\u00e9 jednoduch\u00e9 implement\u00e1cie (ktor\u00e1 bola skvel\u00e1 pre Alore). Python komplikuje pr\u00e1cu s cyklick\u00fdmi importami predov\u0161etk\u00fdm z d\u00f4vodu nejednozna\u010dnosti v\u00fdrazov. Napr\u00edklad, po\u010das oper\u00e1cie prira\u010fovania hodnoty m\u00f4\u017ee v skuto\u010dnosti by\u0165 definovan\u00fd alias typu. Mypy nie v\u017edy dok\u00e1\u017ee identifikova\u0165 tak\u00e9to veci, k\u00fdm nie je spracovan\u00e1 v\u00e4\u010d\u0161ina cyklu importu. V Alore tak\u00fdch nejednozna\u010dnost\u00ed neexistovalo. Zl\u00e9 rozhodnutia prijat\u00e9 na ran\u00fdch f\u00e1zach v\u00fdvoja syst\u00e9mu m\u00f4\u017eu program\u00e1torovi prinies\u0165 nepr\u00edjemn\u00e9 prekvapenie po mnoh\u00fdch rokoch.<\/p>\n<h2>Zhrnutie: cesta k 5 mili\u00f3nom riadkov k\u00f3du a nov\u00fdm horizontom<\/h2>\n<p>\nProjekt mypy pre\u0161iel dlh\u00fa cestu \u2014 od ran\u00fdch prototypov a\u017e po syst\u00e9m, ktor\u00fd kontroluje typy produk\u010dn\u00e9ho k\u00f3du s objemom 4 mili\u00f3ny riadkov. Po\u010das v\u00fdvoja mypy bola uskuto\u010dnen\u00e1 \u0161tandardiz\u00e1cia typov\u00fdch n\u00e1vrhov v Pythone. V s\u00fa\u010dasnosti okolo typiz\u00e1cie k\u00f3du Pythonu vznikol siln\u00fd ekosyst\u00e9m. Objavili sa tu podpora kni\u017en\u00edc, existuj\u00fa pomocn\u00e9 n\u00e1stroje pre IDE a editory, a s\u00fa tu aj nieko\u013eko syst\u00e9mov kontroly typov, z ktor\u00fdch ka\u017ed\u00fd m\u00e1 svoje v\u00fdhody a nev\u00fdhody.<\/p>\n<p>Napriek tomu, \u017ee kontrola typov je u\u017e na Dropboxe pova\u017eovan\u00e1 za nie\u010do samozrejm\u00e9, som presved\u010den\u00fd, \u017ee st\u00e1le \u017eijeme na \u00fasvite typiz\u00e1cie k\u00f3du Python. Mysl\u00edm si, \u017ee technol\u00f3gie kontroly typov bud\u00fa na\u010falej vyv\u00edjan\u00e9 a zdokona\u013eovan\u00e9.<\/p>\n<p>Ak e\u0161te nepou\u017e\u00edvate kontrolu typov vo svojich ve\u013ekorozmern\u00fdch projektoch v Pythone, vedzte, \u017ee teraz je ve\u013emi vhodn\u00fd \u010das na prechod na statick\u00fa typiz\u00e1ciu. Hovoril som s nieko\u013ek\u00fdmi, ktor\u00ed tak\u00fdto prechod urobili. Nikto z nich toho ne\u013eutoval. Kontrola typov rob\u00ed z Pythona jazyk, ktor\u00fd je ove\u013ea lep\u0161\u00ed na v\u00fdvoj ve\u013ek\u00fdch projektov ako oby\u010dajn\u00fd Python.<\/p>\n<p><b>V\u00e1\u017een\u00ed \u010ditatelia!<\/b> Pou\u017e\u00edvate kontrolu typov vo svojich projektoch v Pythone?<\/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 Python k\u00f3du. \u010cas\u0165 3\" src=\"\/wp-content\/uploads\/2019\/10\/bf2bc557ce4481dd87398515bff60e3f.png\" 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 Python k\u00f3du. \u010cas\u0165 3\" src=\"\/wp-content\/uploads\/2019\/10\/098d481c25b3afaba9534c686e8f943a.png\" 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\/468237\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430. \u2192 \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0447\u0430\u0441\u0442\u0438: \u043f\u0435\u0440\u0432\u0430\u044f \u0438 \u0432\u0442\u043e\u0440\u0430\u044f \u0414\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0435 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0415\u0449\u0451 \u043e\u0434\u043d\u043e\u0439 \u0432\u0430\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 (\u044d\u0442\u043e \u0431\u044b\u043b \u0432\u0442\u043e\u0440\u0430\u044f \u043f\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u0432\u043e\u043b\u043d\u043e\u0432\u0430\u0432\u0448\u0430\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0430\u043b \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043e\u043f\u0440\u043e\u0441\u0430\u0445) \u0431\u044b\u043b\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0451\u043c\u0430 \u043a\u043e\u0434\u0430 \u0432 Dropbox, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28992,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-38649","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.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 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-3\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\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 3 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 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-3\" \/>\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:25:04+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:25:04+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 kontrole typov 4 mili\u00f3nov riadkov Python k\u00f3du. \u010cas\u0165 3 | ProHoster","description":"Predstavujeme v\u00e1m tretiu \u010das\u0165 prekladu materi\u00e1lu o ceste, ktor\u00fa pre\u0161la spolo\u010dnos\u0165 Dropbox pri zav\u00e1dzan\u00ed syst\u00e9mu overovania typov Python k\u00f3du.","canonical_url":"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","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 3 | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430.","og:url":"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","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:25:04+00:00","article:modified_time":"2019-10-31T19:25:04+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38649","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:54:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:05:23","updated":"2026-08-11 12:50:30","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\/38649","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=38649"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts\/38649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media\/28992"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media?parent=38649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/categories?post=38649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/tags?post=38649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}