{"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\/sl\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","title":{"rendered":"Pot do preverjanja tipov 4 milijonov vrstic Python kode. Del 3","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Predstavljamo vam tretji del prevoda gradiva o poti, ki jo je pre\u0161la dru\u017eba Dropbox pri uvajanju sistema preverjanja tipov Python kode.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\"><img decoding=\"async\" alt=\"Pot do preverjanja tipov 4 milijonov vrstic Python kode. Del 3\" src=\"\/wp-content\/uploads\/2019\/10\/757669265e870de604388c66adef814d.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u2192 Prej\u0161nji deli: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468233\/\">ena<\/a><\/noindex> in <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\">dva<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Dosego 4 milijonov vrstic tipizirane kode<\/h2>\n<p>\n\u0160e en pomemben cilj (to je bil drugi najbolj priljubljen problem, ki je skrbelo tiste, ki so sodelovali v notranjih anketah) je bil pove\u010dati obseg kode v Dropboxu, pokritega s preverjanjem tipov. Preizkusili smo ve\u010d pristopov za re\u0161itev tega izziva \u2014 od naravnega pove\u010danja obsega tipizirane kode do osredoto\u010danja naporov \u010dlanov ekipe mypy na stati\u010dno in dinami\u010dno avtomatizirano sklepanje tipov. Na koncu se je zdelo, da ne obstaja enostavna zmagovalna strategija, vendar smo uspeli dose\u010di hitro rast obsega Annotirane kode, ki smo jo kombinirali z ve\u010d pristopi.<\/p>\n<p>Zaradi tega je v na\u0161em najve\u010djem Python repozitoriju (z backend kodo) \u0161tevilo vrstic annotirane kode doseglo skoraj 4 milijone. Delo na stati\u010dni tipizaciji kode je trajalo pribli\u017eno tri leta. Mypy zdaj podpira razli\u010dne vrste poro\u010dil o pokritosti kode s tipi, kar poenostavi spremljanje napredka tipizacije. \u0160e posebej lahko sestavimo poro\u010dila za kodo s negotovostmi v tipih, kot so, na primer, eksplicitna uporaba tipov <code>Any<\/code> v oznakah, ki jih ni mogo\u010de preveriti, ali s tistimi, kot so uvozi zunanjih knji\u017enic, ki nimajo oznak tipov. V okviru projekta za izbolj\u0161anje natan\u010dnosti preverjanja tipov v Dropboxu smo prispevali k izbolj\u0161anju definicij tipov (t. i. stub datotek) za nekatere priljubljene odprtokodne knji\u017enice v centraliziranem Python repozitoriju <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/python\/typeshed\">typeshed<\/a><\/noindex>.<\/p>\n<p>Implementirali smo (in standardizirali v naslednjih PEP) nove mo\u017enosti sistema tipov, ki omogo\u010dajo uporabo natan\u010dnej\u0161ih tipov za nekatere specifi\u010dne Python vzorce. Opazen primer tega je <code>TypeDict<\/code>, ki nudi tipe za JSON podobne slovarje, ki imajo fiksno skupino nizov klju\u010dev, kjer ima vsak klju\u010d svojo vrsto. Nadaljevali bomo z raz\u0161irjanjem sistema tipov. Verjetno bomo naslednji korak izbolj\u0161ali podporo Pythonovim zmogljivostim pri delu s \u0161tevilkami.<\/p>\n<p><img decoding=\"async\" alt=\"Pot do preverjanja tipov 4 milijonov vrstic Python kode. Del 3\" src=\"\/wp-content\/uploads\/2019\/10\/297b9e823141d6cb0d2f19f9a78a1153.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>\u0160tevilo vrstic anotiranega kode: stre\u017enik<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Pot do preverjanja tipov 4 milijonov vrstic Python kode. Del 3\" src=\"\/wp-content\/uploads\/2019\/10\/c183a9227e51d847bfdb2b8f6153684f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>\u0160tevilo vrstic anotiranega kode: odjemalec<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Pot do preverjanja tipov 4 milijonov vrstic Python kode. Del 3\" src=\"\/wp-content\/uploads\/2019\/10\/0a8b936fa454a34c09a9c6a2694485c9.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Skupno \u0161tevilo vrstic anotiranega kode<\/i><\/p>\n<p>Tukaj je pregled glavnih zna\u010dilnosti ukrepov, ki smo jih sprejeli za pove\u010danje \u0161tevila anotirane kode v Dropboxu:<\/p>\n<p>Strogost anotiranja. Postopoma smo pove\u010dali zahtevnost glede strogosti anotiranja nove kode. Za\u010deli smo s priporo\u010dili lintra, ki so predlagala dodajanje anotacij v datoteke, v katerih so \u017ee prisotne nekatere anotacije. Zdaj zahtevamo prisotnost tipnih anotacij v novih Python datotekah in v ve\u010dini obstoje\u010dih datotek.<\/p>\n<p>Poro\u010dila o tipizaciji. Tedensko po\u0161iljamo ekipam poro\u010dila o ravni tipizacije njihove kode in dajemo nasvete, kaj bi bilo smiselno anektirati najprej.<\/p>\n<p>Popularizacija mypy. O mypy-ju govorimo na razli\u010dnih dogodkih in se pogovarjamo z ekipami, ter jim pomagamo za\u010deti uporabljati tipne anotacije.<\/p>\n<p>Ankete. Redno izvajamo ankete med uporabniki, da bi ugotovili glavne te\u017eave. Pripravljeni smo iti dovolj dale\u010d, da re\u0161imo te te\u017eave (tudi do ustanovitve novega jezika, da bi pospe\u0161ili mypy!).<\/p>\n<p>U\u010dinkovitost. Z znatnim izbolj\u0161anjem u\u010dinkovitosti mypy smo uporabili demone in mypyc. To smo storili, da bi omilili nev\u0161e\u010dnosti, ki nastanejo pri anotiranju, in omogo\u010dili delo z ve\u010djimi koli\u010dinami kode.<\/p>\n<p>Integracija z uredniki. Ustvarili smo orodja za podporo zagonu mypy v priljubljenih urejevalnikih v Dropboxu. Sem spadajo PyCharm, Vim in VS Code. To je mo\u010dno poenostavilo postopek opravila anotiranja kode in preverjanja njene delovanja. Tak\u0161ne akcije so obi\u010dajne pri anotiranju obstoje\u010de kode.<\/p>\n<p>Statisti\u010dna analiza. Ustvarili smo orodje za izhod funkcijskih podpisov z uporabo stati\u010dne analize. To orodje lahko deluje le v razmeroma preprostih situacijah, vendar nam je pomagalo brez ve\u010djih te\u017eav pove\u010dati pokritost kode s tipi.<\/p>\n<p>Podpora zunanjih knji\u017enic. V mnogih na\u0161ih projektih uporabljamo nabor orodij SQLAlchemy. V njem se uporabljajo dinami\u010dne funkcionalnosti Pythona, ki jih tipi PEP 484 ne morejo neposredno modelirati. V skladu s PEP 561 smo ustvarili ustrezen stub-dokument in napisali vti\u010dnik za mypy (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dropbox\/sqlalchemy-stubs\">\u043e\u043f\u0435\u043d\u0441\u043e\u0440\u0441\u043d\u044b\u0439<\/a><\/noindex>), ki izbolj\u0161uje podporo za SQLAlchemy.<\/p>\n<h2>Te\u017eave, s katerimi smo se sre\u010dali<\/h2>\n<p>\nPot do 4 milijonov vrstic tipizirane kode ni bila vedno enostavna. Na tej poti smo naleteli na \u0161tevilne ovire in naredili nekaj napak. To so nekatere te\u017eave, s katerimi smo se sre\u010dali. Upamo, da bo pripoved o njih pomagala drugim, da se izognejo podobnim te\u017eavam.<\/p>\n<p>Izpu\u0161\u010deni datoteke. Za\u010deli smo z raznovrstnim pregledom le majhnega \u0161tevila datotek. Vse, kar ni bilo vklju\u010deno v to \u0161tevilo datotek, ni bilo pregledovano. Datoteke so bile dodane v pregled, ko so se v njih pojavile prve anotacije. \u010ce je bila kaj uvo\u017eeno iz modula, ki je bil zunaj obmo\u010dja pregleda, je \u0161lo za delo z vrednostmi tipa <code>Any<\/code>, ki niso bile sploh preverjene. To je povzro\u010dilo znatno izgubo natan\u010dnosti tipizacije, zlasti v zgodnjih fazah migracije. Tak pristop je \u0161e vedno deloval presenetljivo dobro, \u010deprav je bila znana situacija, ko je dodajanje datotek v obmo\u010dje pregleda razkrilo te\u017eave v drugih delih kode. V najhuj\u0161em primeru, ko sta se zdru\u017eili dve izolirani podro\u010dji kode, pri katerih so bili tipi neodvisno preverjeni, se je izkazalo, da tipi teh podro\u010dij niso zdru\u017eljivi. To je pomenilo potrebo po spremembah v veliko anotacijah. Zdaj, ko se ozremo nazaj, razumemo, da bi bilo bolje, da bi \u010dim prej dodali osnovne knji\u017eni\u010dne module v obmo\u010dje tipizacije mypy. To bi na\u0161e delo naredilo veliko bolj predvidljivo.<\/p>\n<p>Annotacija starega kode. Ko smo za\u010deli delo, smo imeli pribli\u017eno 4 milijone vrstic obstoje\u010de kode v Pythonu. Bilo je jasno, da je annotiranje vse te kode zahtevna naloga. Ustvarili smo orodje, imenovano PyAnnotate, ki lahko zbira informacije o tipih med izvajanjem testov in dodaja annotacije tipov v kodo, temelje\u010de na zbranih informacijah. Vendar pa posebnega \u0161ir\u0161ega uvajanja tega orodja nismo opazili. Zbiranje informacij o tipih je bilo po\u010dasno, samodejno generirane annotacije so pogosto zahtevale \u0161tevilne ro\u010dne popravke. Razmi\u0161ljali smo o samodejnem zagonu tega orodja pri vsakem pregledu kode ali o zbiranju informacij o tipih na podlagi analize majhnega \u0161tevila dejanskih omre\u017enih zahtevkov, vendar smo se odlo\u010dili, da tega ne storimo, saj je bilo kateri od teh pristopov preve\u010d tvegano.<\/p>\n<p>Na koncu lahko ugotovimo, da je ve\u010dina kode ro\u010dno annotirana s strani njenih lastnikov. Da bi usmerili ta postopek v pravo smer, pripravljamo poro\u010dila o zlasti pomembnih modulih in funkcijah, ki jih je treba annotirati. Na primer, pomembno je, da knji\u017eni\u010dni modul, ki se uporablja v stotinah mest, opremimo z annotacijami tipov. Stara storitev, ki jo nadome\u0161\u010da nova, pa ni ve\u010d tako pomembno annotirati. Poleg tega eksperimentiramo z uporabo stati\u010dne analize za ustvarjanje annotacij tipov za staro kodo.<\/p>\n<p>Cikli\u010dni uvozi. Prethodno sam spomenuo cikli\u010dne uvoze (o \"klup\u010dima zavisnosti\"), \u010dije postojanje ote\u017eava ubrzanje mypy-a. Tako\u0111e, morali smo ozbiljno raditi na tome da mypy podr\u017ei sve vrste idioma, \u010diji uzrok su ovi cikli\u010dni uvozi. Nedavno smo zavr\u0161ili veliki projekat redizajna sistema, koji je ispravio ve\u0107inu problema mypy-a vezanih za cikli\u010dne uvoze. Ovi problemi su, zapravo, potekli iz vrlo ranih dana projekta, jo\u0161 iz Alorea, nastavnog jezika na koji je projekat mypy prvobitno bio orijentisan. Sintaksa Alorea olak\u0161ava re\u0161avanje problema cikli\u010dnih import komandi. Savremeni mypy je nasledio neka ograni\u010denja iz svoje rane jednostavne implementacije (koja je bila odli\u010dna za Alore). Python ote\u017eava rad sa cikli\u010dnim uvozima uglavnom zbog nejasno\u0107a izraza. Na primer, tokom operacije dodele vrednosti mo\u017ee se zapravo definisati alias tipa. Mypy ne mo\u017ee uvek da identifikuje sli\u010dne stvari dok ve\u0107i deo ciklusa uvoza ne bude obra\u0111en. U Alore nije bilo takvih nejasno\u0107a. Neuspe\u0161na re\u0161enja doneta u ranim fazama razvoja sistema mogu doneti programeru neprijatno iznena\u0111enje nakon mnogo godina.<\/p>\n<h2>Rezultati: put do 5 miliona linija koda i novim horizontima<\/h2>\n<p>\nProjekat mypy je pro\u0161ao dug put \u2014 od ranih prototipova do sistema koji kontroli\u0161e tipove proizvodnog koda obima od 4 miliona linija. Tokom razvoja mypy-a standardizovani su saveti o tipovima u Pythonu. Danas se oko tipizacije Python koda razvila mo\u0107na ekosistem. Tu su podr\u0161ke za biblioteke, alati za IDE i ure\u0111iva\u010de, i nekoliko sistema za kontrolu tipova, od kojih svaki ima svoje prednosti i mane.<\/p>\n<p>Iako se provera tipova ve\u0107 smatra ne\u010dim \u0161to je u Dropbox-u op\u0161teprihva\u0107eno, siguran sam da jo\u0161 uvek \u017eivimo u zoru tipizacije Python koda. Mislim da \u0107e tehnologije za proveru tipova nastaviti da se razvijaju i usavr\u0161avaju.<\/p>\n<p>\u010ce \u0161e niste uporabljali preverjanja tipov v svojem velikem Python projektu, vedite, da je zdaj zelo primeren \u010das, da za\u010dnete prehod na stati\u010dno tipizacijo. Pogovarjal sem se z nekaterimi, ki so izvedli tak prehod. Nih\u010de od njih ni ob\u017ealoval. Nadzor tipov pretvori Python v jezik, ki je veliko bolj primeren za razvoj velikih projektov kot \"navadni Python\".<\/p>\n<p><b>Spo\u0161tovani bralci!<\/b> Ali uporabljate nadzor tipov v svojih Python projektih?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Pot do preverjanja tipov 4 milijonov vrstic Python kode. Del 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=\"Pot do preverjanja tipov 4 milijonov vrstic Python kode. Del 3\" src=\"\/wp-content\/uploads\/2019\/10\/098d481c25b3afaba9534c686e8f943a.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Izvor: <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.4 - 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\/sl\/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.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sl_SI\" \/>\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\/sl\/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\udd47 Pot do preverjanja tipov 4 milijonov vrstic Python kode. Del 3 | ProHoster","description":"Predstavljamo vam tretji del prevoda gradiva o poti, ki jo je pre\u0161la dru\u017eba Dropbox pri uvajanju sistema preverjanja tipov Python kode.","canonical_url":"https:\/\/prohoster.info\/sl\/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":"sl_SI","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\/sl\/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\/sl\/wp-json\/wp\/v2\/posts\/38649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/comments?post=38649"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/38649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media\/28992"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media?parent=38649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/categories?post=38649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/tags?post=38649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}