{"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\/et\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","title":{"rendered":"Teekond 4 miljoni rea Python koodi t\u00fc\u00fcpide kontrollimise juurde. Osa 2","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>T\u00e4na avaldame teise osa t\u00f5lkest materjalist, mis k\u00e4sitleb, kuidas Dropbox korraldas miljonite ridade Python-koodi t\u00fc\u00fcpide kontrolli.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\"><img decoding=\"async\" alt=\"Teekond 4 miljoni rea Python koodi t\u00fc\u00fcpide kontrollimise juurde. Osa 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\/\">Loe esimest osa<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Ametlik t\u00fc\u00fcpide tugi (PEP 484)<\/h2>\n<p>\nMe tegime esimesed t\u00f5sised katsed mypy-ga Dropboxis 2014. aasta Hack Weeki ajal. Hack Week on Dropboxi \u00fcritus, mis toimub \u00fche n\u00e4dala jooksul. Sellel ajal saavad t\u00f6\u00f6tajad t\u00f6\u00f6tada k\u00f5ikide projektide kallal, mis neile huvi pakuvad! Paljud tuntud tehnoloogia projektid Dropboxis algasid just sellistel \u00fcritustel. Selle katse tulemusena j\u00f5udsime j\u00e4reldusele, et mypy n\u00e4eb v\u00e4lja paljut\u00f5otav, kuigi see projekt ei olnud veel laiemaks kasutamiseks valmis.<\/p>\n<p>Sel ajal k\u00fcpses \u00f5hus idee Python t\u00fc\u00fcpide n\u00e4pun\u00e4idete andmise s\u00fcsteemide standardiseerimise \u00fcle. Nagu ma juba \u00fctlesin, alates Python 3.0-st sai funktsioonide t\u00fc\u00fcpide annotatsioonidega t\u00f6\u00f6tada, kuid need olid vaid meelevaldsed v\u00e4ljendid, ilma kindla s\u00fcntaksita ja semantikat. Programmi k\u00e4ivitamisel ignoreeriti neid annotatsioone suuremasti lihtsalt. P\u00e4rast Hack Weeki alustasime standardiseerimise nimel t\u00f6\u00f6tamist. See t\u00f6\u00f6 viis PEPe 484 s\u00fcnnini. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.python.org\/dev\/peps\/pep-0484\/\">PEP 484<\/a><\/noindex> (selle dokumendi koostamisel olid osalised Guido van Rossum, Luk\u00e1\u0161 Langa ja mina).<\/p>\n<p>Meie motiive saab vaadelda kahel viisil. Esiteks loodame, et kogu Python'i \u00f6kos\u00fcsteem v\u00f5iks omaks v\u00f5tta \u00fchise l\u00e4henemise t\u00fc\u00fcbi vihjete (type hints \u2014 Python'is kasutatav termin, mis vastab m\u00f5istele 't\u00fc\u00fcbi annotatsioon') kasutamisele. Arvestades v\u00f5imalikke riske, oleks see parem, kui kasutada palju \u00fcksteisega mittesobivaid l\u00e4henemisi. Teiseks soovisime avatud arutelu t\u00fc\u00fcpide annotatsiooni mehhanismide \u00fcle paljude Python'i kogukonna liikmetega. Osaliselt oli see soov tingitud vajadusest mitte n\u00e4ida 'h\u00e4das olevat' keele p\u00f5hialustest laiemale Python'i programmeerijate massile. See on d\u00fcnaamiliselt t\u00fc\u00fcbitud keel, tuntud 'partide t\u00fc\u00fcbistamise' poolest. Alguses ei saanud kogukonnas kahtlustesse suhtumise v\u00e4ltimine t\u00fc\u00fcbi staatilise t\u00fc\u00fcbistamise ideede osas. Kuid selline hoiak n\u00f5rgenes l\u00f5puks \u2014 p\u00e4rast seda, kui selgus, et staatilist t\u00fc\u00fcbistamist ei plaanita kohustuslikuks muuta (ja p\u00e4rast seda, kui inimesed m\u00f5istsid, et see on tegelikult kasulik).<\/p>\n<p>K\u00e4ivitatud s\u00fcntaksit\u00fc\u00fcbid olid l\u00f5puks v\u00e4ga sarnased sellele, mida toona toetas mypy. PEP 484 dokument ilmus koos Python 3.5-ga 2015. aastal. Python ei olnud enam keel, mis toetab ainult d\u00fcnaamilist t\u00fc\u00fcpimist. Mulle meeldib m\u00f5elda sellele s\u00fcndmusele kui olulisele verstapostile Python'i ajaloos.<\/p>\n<h2>Migratsiooni alustamine<\/h2>\n<p>\n2015. aasta l\u00f5pus loodi Dropboxis mypy arendamiseks kolmest inimesest koosnev meeskond. Nendeks olid Guido van Rossum, Greg Price ja David Fisher. Sellest hetkest alates hakkas olukord kiirelt arenema. MyPy kasvuteel oli esimeseks takistuseks j\u00f5udlus. Nagu ma eelnevalt mainisin, m\u00f5tlesin projekti varajases arengufaasis mypy teostuse \u00fcleviimisele C keelde, kuid see m\u00f5te j\u00e4i sel hetkel k\u00f5rvale. Olime ummikseisus, kuna s\u00fcsteemi k\u00e4itamiseks kasutati CPython'i t\u00f5lgendajat, mis ei olnud piisavalt kiire selliste t\u00f6\u00f6riistade jaoks nagu mypy. (Projekti PyPy, alternatiivne JIT-kompileerijaga Python'i teostus, ei aidanud ka meid.)<\/p>\n<p>Kuid siin aitasid meid m\u00f5ned algoritmilised t\u00e4iustused. Esimeseks v\u00f5imsaks \"kiirendajaks\" sai inkrementaalne kontroll. Selle t\u00e4iustuse idee oli lihtne: kui k\u00f5ik mooduli s\u00f5ltuvused p\u00e4rast eelmise mypy k\u00e4ivitamise hetke ei ole muutunud, siis saame s\u00f5ltuvustega t\u00f6\u00f6tamisel kasutada andmeid, mis on eelmisel seansil vahem\u00e4llu salvestatud. Me pidime vaid kontrollima t\u00fc\u00fcpe muudetud failides ja nendes failides, mis s\u00f5ltusid neist. Mypy l\u00e4ks isegi natuke kaugemale: kui mooduli v\u00e4line liides ei muutunud, siis pidas mypy \u00f5igeks, et teisi mooduleid, mis seda moodulit impordivad, ei pea uuesti kontrollima.<\/p>\n<p>Inkremendiline kontroll aitas meil suure hulga olemasoleva koodi annotatsioonide lisamisel m\u00e4rkimisv\u00e4\u00e4rselt. Probleem on selles, et see protsess sisaldab tavaliselt mitmeid iteratiivseid mypy jooksutusi, kuna annotatsioone lisatakse j\u00e4rk-j\u00e4rgult koodile ja parendatakse j\u00e4rk-j\u00e4rgult. Esimene mypy jooks oli ikka veel v\u00e4ga aeglane, kuna selle k\u00e4ivitamisel tuli kontrollida palju s\u00f5ltuvusi. Seet\u00f5ttu rakendasime olukorra parandamiseks kaugk\u00fchveldustehnoloogia. Kui mypy tuvastab, et kohalik vahem\u00e4lu on t\u00f5en\u00e4oliselt aegunud, laadib ta kogu koodibaasi praeguse vahem\u00e4lu snapshot'i tsentraliseeritud hoidlast. Seej\u00e4rel viib ta l\u00e4bi inkremendilise kontrolli, kasutades seda snapshot'i. See t\u00f5i meid veel \u00fche suure sammu l\u00e4hemale mypy j\u00f5udluse suurendamisele.<\/p>\n<p>See oli kiire ja loomulik t\u00fc\u00fcpide kontrollimise s\u00fcsteemi rakendamise periood Dropboxis. 2016. aasta l\u00f5puks oli meil juba umbes 420 000 rida Python-koodi, millel olid t\u00fc\u00fcpide annotatsioonid. Paljud kasutajad olid t\u00fc\u00fcpide kontrollimise suhtes entusiastlikud. Dropboxis kasutas mypy j\u00e4rjest rohkem arendajameeskondi.<\/p>\n<p>K\u00f5ik n\u00e4is toona h\u00e4sti, kuid meil oli veel palju t\u00f6\u00f6d teha. Alustasime regulaarsete sisemiste kasutajauuringute l\u00e4biviimist, et tuvastada projekti probleemsed kohad ja m\u00f5ista, milliseid k\u00fcsimusi tuleb k\u00f5igepealt lahendada (seda praktikat kasutatakse ettev\u00f5ttes ka t\u00e4na). Selgus, et kaks \u00fclesannet olid k\u00f5ige olulisemad. Esimene \u2013 koodi katvuse suurendamine t\u00fc\u00fcpidega, teine \u2013 mypy kiirus. Oli t\u00e4iesti selge, et meie t\u00f6\u00f6 mypy kiirendamise ja selle integreerimise kallal ettev\u00f5tte projektides oli veel kaugel l\u00f5ppsaamisest. T\u00e4ielikult teades nende kahe \u00fclesande t\u00e4htsust, asusime neid lahendama.<\/p>\n<h2>Rohkem j\u00f5udlust!<\/h2>\n<p>\nInkrementaalsed kontrollid kiirusid mypy'd, kuid see t\u00f6\u00f6riist polnud ikka veel piisavalt kiire. Paljud inkrementaalsed kontrollid kestisid umbes minuti. Selle p\u00f5hjuseks olid ts\u00fcklilised impordid. See ei \u00fcllata t\u00f5en\u00e4oliselt kedagi, kes on t\u00f6\u00f6tanud suurte Pythoniga kirjutatud koodibaasidega. Meil olid komplektid sadadest moodulitest, millest iga\u00fcks kaudselt importis k\u00f5ik teised. Kui m\u00f5ni fail ts\u00fcklite impordis muutus, pidi mypy t\u00f6\u00f6tlema k\u00f5ik failid, mis kuulusid sellesse ts\u00fcklisse, ning sageli ka k\u00f5ik moodulid, mis importisid mooduleid sellest ts\u00fcklist. \u00dcks selline ts\u00fckkel oli kurikuulus \u201es\u00f5ltuvuste kook\u201d, mis p\u00f5hjustas Dropboxis palju probleeme. \u00dchel hetkel sisaldas see struktuur sadu module, mida importisid, otse v\u00f5i kaudselt, mitmed testid, ning seda kasutati ka tootmiskoodis.<\/p>\n<p>Me arutasime v\u00f5imalust ts\u00fckliliste s\u00f5ltuvuste \"lahendamiseks\", kuid meil polnud selleks ressursse. Koodi oli liiga palju, millega me ei olnud tuttavad. L\u00f5ppkokkuv\u00f5ttes valisime alternatiivse l\u00e4henemise. Otsustasime, et mypy peaks ka probleemsete s\u00f5ltuvuste korral kiiresti t\u00f6\u00f6tama. Me saavutasime selle eesm\u00e4rgi mypy deemoniga. Deemon on serveriprotsess, mis pakub kahte huvitavat funktsiooni. Esiteks \u2013 ta hoiab kogu koodibaasi teavet m\u00e4lus. See t\u00e4hendab, et igal mypy k\u00e4ivitamisel ei pea laadima tuhandeid imporditud s\u00f5ltuvustega seotud vahem\u00e4lus olevaid andmeid. Teiseks \u2013 ta anal\u00fc\u00fcsib s\u00f5ltuvusi p\u00f5hjalikult, v\u00e4ikeste struktuuriliste \u00fcksuste tasandil. N\u00e4iteks, kui funktsioon <code>foo<\/code> kutsub ellu funktsiooni <code>bar<\/code>, siis on s\u00f5ltuvus <code>foo<\/code> alates <code>bar<\/code>. Kui fail muutub, siis demon t\u00f6\u00f6tleb alguses ainult muutunud faili isoleeritult. Seej\u00e4rel vaatab ta selle faili muudatusi, mis on v\u00e4ljastpoolt n\u00e4htavad, n\u00e4iteks muutunud funktsioonide allkirjat. Demon kasutab importide \u00fcksikasjalikku teavet t\u00e4iendava kontrolli jaoks ainult nende funktsioonide kohta, mis t\u00f5eliselt kasutavad muudetud funktsiooni. Sellise l\u00e4henemisega tuleb tavaliselt kontrollida vaid m\u00f5nda funktsiooni.<\/p>\n<p>Kogu selle elluviimine osutus keeruliseks, kuna algne mypy teostus oli tugevalt suunatud \u00fche faili kaupa t\u00f6\u00f6tlemisele. Me pidime silmitsi seisma paljude piirjuhtumitega, mille tekkimine n\u00f5udis korduvaid kontrollimisi, kui koodis midagi muudetud oli. N\u00e4iteks juhtub see siis, kui klassile m\u00e4\u00e4ratakse uus p\u00f5hi klass. P\u00e4rast seda, kui olime saavutanud soovitud tulemuse, suutsime suurendada enamikku inkrementsest kontrollist vaid m\u00f5ne sekundi peale. Meie jaoks tundus see suur v\u00f5it.<\/p>\n<h2>Veelgi rohkem j\u00f5udlust!<\/h2>\n<p>\nKoos eemaldatava vahem\u00e4luga, millest ma eespool r\u00e4\u00e4gin, lahendas mypy praktiliselt t\u00e4ielikult probleemid, mis tekkisid siis, kui programmeerija k\u00e4ivitas t\u00fc\u00fcpide kontrolli, muutes v\u00e4ikest hulka faile. Siiski j\u00e4i s\u00fcsteemi j\u00f5udlus isegi k\u00f5ige ebasoodsamas kasutusvariandis kaugele optimaalsest. Mypy puhas k\u00e4ivitamine v\u00f5is v\u00f5tta rohkem kui 15 minutit. Ja see oli palju rohkem, kui me oleksime soovinud. Igal n\u00e4dalal olukord halvenes, kuna programmeerijad j\u00e4tkasid uue koodi kirjutamist ja olemasoleva koodi annotatsioonide lisamist. Meie kasutajad ootasid endiselt suuremat j\u00f5udlust ja me olime hea meelega valmis neid toetama.<\/p>\n<p>Otsustasime tagasi p\u00f6\u00f6rduda \u00fche varasema idee juurde mypy kohta. Ehkki Cythoniga (see on s\u00fcsteem, mis v\u00f5imaldab t\u00f5lkida Pythonis kirjutatud koodi C-koodiks) tehtud eksperimendi k\u00e4igus ei saavutanud me n\u00e4htavat kiiruskasvu, otsustasime elu sisse puhuda ideele luua oma kompilaator. Kuna mypy koodibaas (kirjutatud Pythonis) sisaldas juba k\u00f5iki vajalikke t\u00fc\u00fcbi annotatsioone, tundus proovi tegemine nende annotatsioonide kasutamiseks s\u00fcsteemi kiirusel p\u00f5hinev. Loodud protot\u00fc\u00fcp n\u00e4itas erinevates mikro-benchm\u00e4rkides \u00fcle 10-kordset j\u00f5udluskasvu. Meie idee oli kompileerida Pythonimooduleid C-mooduliteks Cythoniga ja muuta t\u00fc\u00fcbi annotatsioonid t\u00fc\u00fcbi kontrollideks, mis teostatakse programmi k\u00e4ivitamise ajal (t\u00fc\u00fcbi annotatsioone ignoreeritakse tavaliselt programmide k\u00e4ivitamisel ja neid kasutatakse ainult t\u00fc\u00fcpide kontrollimise s\u00fcsteemide poolt). Me plaanisime tegelikult mypy rakenduse \u00fcleviimist Pythonist keelde, mis on statiliselt t\u00fcpiseeritud, mis n\u00e4eks v\u00e4lja (ja enamasti ka t\u00f6\u00f6taks) t\u00e4pselt nagu Python. (See liik keeltevaheline migreerimine on saanud mypy projekti traditsiooniks. Algne mypy rakendus oli kirjutatud Alore'is, seej\u00e4rel oli selles Java ja Python'i s\u00fcntaktiline h\u00fcbriid.)<\/p>\n<p>CPythoni laienduste API orienteeritus oli v\u00f5tmet\u00e4htsusega meie projekti haldamise v\u00f5imekuse s\u00e4ilitamisel. Me ei pidanud rakendama virtuaalmasinat ega vajalikke raamatukogusid nagu mypy. Lisaks oleks kogu Python \u00f6kos\u00fcsteem endiselt kergesti ligip\u00e4\u00e4setav, koos k\u00f5igi t\u00f6\u00f6riistadega (nt pytest). See v\u00f5imaldas meil j\u00e4tkata t\u00f5lgendatava Python koodi kasutamist arendust\u00f6\u00f6s, mis andis meile v\u00f5imaluse teha kiireid koodimuudatusi ja testimist, mitte oodata koodi kompileerimist. See tundus, nagu j\u00f5uaksime suurep\u00e4raselt tasakaalu hoidma, ja me nautisime seda.<\/p>\n<p>Kompilaator, mille me nimetasime mypyc (sest front-endina kasutab ta t\u00fc\u00fcpide anal\u00fc\u00fcsimiseks mypy), osutus \u00fcsna edukaks projektiks. \u00dcldiselt saavutame me umbes 4-kordse kiiruskasvu sagedaste mypy k\u00e4ivitamiste juures ilma vahem\u00e4lu kasutamata. Projekti mypyc arendamine v\u00f5ttis meie v\u00e4ikeselt meeskonnalt, kuhu kuulusid Michael Sullivan, Ivan Levkivski, Hugh Han ja mina, aega umbes 4 kalendrikuu. See t\u00f6\u00f6maht oli tunduvalt v\u00e4iksem, kui see oleks olnud mypy \u00fcmberkirjutamiseks n\u00e4iteks C++-s v\u00f5i Go-s. Muudatusi, mida me projekti pidime tegema, oli samuti oluliselt v\u00e4hem kui oleks pidanud tegema selle \u00fcmberkirjutamiseks teises keeles. Me lootsime ka, et saame viia mypyc tasemele, kus saavad seda kasutada ka teised Dropboxi arendajad oma koodi kompileerimiseks ja kiirusel kiirendamiseks.<\/p>\n<p>Selle taseme j\u00f5udmiseks tuli meil rakendada mitmeid huvitavaid insenerilahendusi. Kompilaator suudab paljude toimingute t\u00e4itmist kiirendada, kasutades kiireid madala taseme C-konstruktsioone. N\u00e4iteks t\u00f5lgitakse kompileeritud funktsiooni kutsumine C-funktsiooni kutsumiseks. Selliste v\u00e4ljakutsete t\u00e4itmine on oluliselt kiirem kui t\u00f5lgendatud funktsiooni v\u00e4ljakutse. Teatud toimingud, nagu s\u00f5naraamatutest otsimine, tuginesid endiselt tavap\u00e4raste C-API v\u00e4ljakutsete kasutamisele CPythonis, mis p\u00e4rast kompileerimist osutusid vaid natuke kiiremateks. Oleme suutnud k\u00f5rvaldada t\u00f5lgendamise tekitatud t\u00e4iendava koormuse, kuid see t\u00f5i antud juhul vaid v\u00e4ikese kasvu j\u00f5udluses.<\/p>\n<p>Koodist k\u00f5ige levinumate 'aeglike' operatsioonide tuvastamiseks tegime koodiprofiilimist. Olles saadud andmetega varustatud, \u00fcritasime kas nii 'h\u00e4\u00e4lestada' mypyc, et see genereeriks kiiremat C-koodi sarnaste operatsioonide jaoks, v\u00f5i kirjutada vastav Python-kood \u00fcmber, kasutades kiiremaid operatsioone (m\u00f5nikord ei olnud meil lihtsalt piisavalt lihtsat lahendust sellele v\u00f5i teisele probleemile). Python-koodi \u00fcmberkirjutamine osutus sageli kergemaks probleemilahenduseks kui sama transformatsiooni automaatne teostamine kompilaatoris. PIKAJAUGU plaanime paljusid neist transformatsioonidest automatiseerida, kuid tol hetkel keskendusime sellele, et minimaalsete pingutustega mypy\u2019d kiirendada. Sel teel l\u00f5ikasime m\u00f5ned nurgad.<\/p>\n<p>J\u00e4tkub\u2026<\/p>\n<p><b>Lugupidamisega lugejad!<\/b> Milliseid muljeid j\u00e4ttis teid projekti mypy kohta, kui kuulsisite selle olemasolust?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Teekond 4 miljoni rea Python koodi t\u00fc\u00fcpide kontrollimise juurde. Osa 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=\"Teekond 4 miljoni rea Python koodi t\u00fc\u00fcpide kontrollimise juurde. Osa 2\" src=\"\/wp-content\/uploads\/2019\/09\/263173dd3ab487da330ff9063e3c180e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Allikas: <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 4.9.10 - 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. \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\" \/>\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\/et\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"et_EE\" \/>\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. \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\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/et\/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\udd47Teekond 4 miljoni rea Python-koodi t\u00fc\u00fcbikontrollini. Osa 2 | ProHoster","description":"T\u00e4na avaldame teise osa materjali t\u00f5lkest selle kohta, kuidas Dropbox korraldas mitme miljoni rea Python-koodi t\u00fc\u00fcbi kontrolli. \u2192 Loe esimest osa Ametlik t\u00fc\u00fcbi tugi (PEP 484) Viisime koos mypy esimesed t\u00f5sised katsed l\u00e4bi Dropboxis 2014. aasta Hack Week'i ajal. Hack Week on Dropboxis korraldatav \u00fcritus, mis kestab \u00fche n\u00e4dala. Sel ajal","canonical_url":"https:\/\/prohoster.info\/et\/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":"et_EE","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. \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","og:url":"https:\/\/prohoster.info\/et\/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":null,"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-01-23 22:13:19"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/38479","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/comments?post=38479"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/38479\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media\/28879"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=38479"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=38479"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=38479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}