{"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\/sv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","title":{"rendered":"V\u00e4gen till typkontroll av 4 miljoner rader Python-kod. Del 3","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Vi presenterar tredje delen av \u00f6vers\u00e4ttningen av materialet om den resa som Dropbox har genomg\u00e5tt f\u00f6r att inf\u00f6ra ett system f\u00f6r typkontroll av Python-kod.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\"><img decoding=\"async\" alt=\"V\u00e4gen till typkontroll av 4 miljoner rader Python-kod. Del 3\" src=\"\/wp-content\/uploads\/2019\/10\/757669265e870de604388c66adef814d.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u2192 Tidigare delar: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468233\/\">f\u00f6rsta<\/a><\/noindex> och <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\">tv\u00e5<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Att n\u00e5 4 miljoner rader typad kod<\/h2>\n<p>\nEn annan viktig uppgift (detta var det n\u00e4st mest popul\u00e4ra problemet som oroade dem som deltog i interna enk\u00e4ter) var att \u00f6ka m\u00e4ngden kod i Dropbox som t\u00e4cks av typkontroller. Vi testade flera tillv\u00e4gag\u00e5ngss\u00e4tt f\u00f6r att l\u00f6sa denna uppgift - fr\u00e5n naturlig tillv\u00e4xt av den typade kodbasen till att fokusera insatserna f\u00f6r mypy-teamet p\u00e5 statisk och dynamisk automatisk typutvinning. Slutligen skapades intrycket att det inte finns n\u00e5gon enkel vinnande strategi, men vi lyckades uppn\u00e5 en snabb \u00f6kning av m\u00e4ngden annoterad kod genom att kombinera flera angreppss\u00e4tt.<\/p>\n<p>Som ett resultat hade v\u00e5r st\u00f6rsta Python-repo (med backend-kod) n\u00e4stan 4 miljoner rader annoterad kod. Arbetet med statisk typning av koden genomf\u00f6rdes under cirka tre \u00e5r. Mypy st\u00f6der nu olika typer av rapporter om typnings t\u00e4ckning, som f\u00f6renklar \u00f6vervakningen av typningsprocessen. Specifikt kan vi generera rapporter f\u00f6r kod med typos\u00e4kerheter, som till exempel ers\u00e4ttande typer <code>Any<\/code> i annotationerna som inte kan verifieras, eller s\u00e5dana som importerar externa bibliotek som saknar typanoteringar. Som en del av projektet f\u00f6r att f\u00f6rb\u00e4ttra noggrannheten i typkontrollen i Dropbox har vi bidragit till f\u00f6rb\u00e4ttringen av typdefinitionerna (de s\u00e5 kallade stub-filerna) f\u00f6r n\u00e5gra popul\u00e4ra open-source-bibliotek i det centraliserade Python-repoet <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/python\/typeshed\">typeshed<\/a><\/noindex>.<\/p>\n<p>Vi har implementerat (och standardiserat i efterf\u00f6ljande PEP) nya funktioner i typ systemet som m\u00f6jligg\u00f6r mer exakta typer f\u00f6r vissa specifika Python-m\u00f6nster. Ett viktigt exempel p\u00e5 detta \u00e4r <code>TypeDict<\/code>, som tillhandah\u00e5ller typer f\u00f6r JSON-liknande ordb\u00f6cker som har en fast upps\u00e4ttning str\u00e4ngnycklar, var och en med ett v\u00e4rde av sin egen typ. Vi kommer att forts\u00e4tta att ut\u00f6ka typ systemet. Troligtvis blir v\u00e5rt n\u00e4sta steg att f\u00f6rb\u00e4ttra st\u00f6det f\u00f6r Python-funktioner som arbetar med siffror.<\/p>\n<p><img decoding=\"async\" alt=\"V\u00e4gen till typkontroll av 4 miljoner rader Python-kod. Del 3\" src=\"\/wp-content\/uploads\/2019\/10\/297b9e823141d6cb0d2f19f9a78a1153.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Antal rader av annoterad kod: server<\/i><\/p>\n<p><img decoding=\"async\" alt=\"V\u00e4gen till typkontroll av 4 miljoner rader Python-kod. Del 3\" src=\"\/wp-content\/uploads\/2019\/10\/c183a9227e51d847bfdb2b8f6153684f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Antal rader av annoterad kod: kund<\/i><\/p>\n<p><img decoding=\"async\" alt=\"V\u00e4gen till typkontroll av 4 miljoner rader Python-kod. Del 3\" src=\"\/wp-content\/uploads\/2019\/10\/0a8b936fa454a34c09a9c6a2694485c9.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Totalt antal rader av annoterad kod<\/i><\/p>\n<p>H\u00e4r \u00e4r en \u00f6versikt \u00f6ver de huvudsakliga funktionerna i de \u00e5tg\u00e4rder vi har vidtagit f\u00f6r att \u00f6ka m\u00e4ngden annoterad kod i Dropbox:<\/p>\n<p>Strikthet i annoteringen. Vi har gradvis \u00f6kat kraven p\u00e5 strikthet f\u00f6r annotering av ny kod. Vi b\u00f6rjade med linternas rekommendationer, d\u00e4r vi f\u00f6reslog att l\u00e4gga till annotationer i filer som redan hade vissa annoteringar. Nu kr\u00e4ver vi att typannotationer finns i nya Python-filer och i de flesta befintliga filer.<\/p>\n<p>Typningsrapporter. Vi skickar veckovisa rapporter till teamen om typningsgraden av deras kod och ger f\u00f6rslag p\u00e5 vad som b\u00f6r annoteras f\u00f6rst.<\/p>\n<p>Fr\u00e4mjande av mypy. Vi pratar om mypy p\u00e5 olika evenemang och kommunicerar med teamen f\u00f6r att hj\u00e4lpa dem komma ig\u00e5ng med typannotationer.<\/p>\n<p>Unders\u00f6kningar. Vi genomf\u00f6r periodiska anv\u00e4ndarunders\u00f6kningar f\u00f6r att identifiera de st\u00f6rsta problemen. Vi \u00e4r beredda att g\u00e5 ganska l\u00e5ngt f\u00f6r att l\u00f6sa dessa problem (inklusive att skapa ett nytt spr\u00e5k f\u00f6r att p\u00e5skynda mypy!).<\/p>\n<p>Prestanda. Vi har avsev\u00e4rt f\u00f6rb\u00e4ttrat prestandan av mypy genom att anv\u00e4nda en daemon och mypyc. Detta gjordes f\u00f6r att j\u00e4mna ut obehagligheter som uppst\u00e5r vid annoteringen och f\u00f6r att kunna hantera stora kodm\u00e4ngder.<\/p>\n<p>Integration med redakt\u00f6rer. Vi har skapat verktyg f\u00f6r att st\u00f6dja k\u00f6rning av mypy i de redakt\u00f6rer som \u00e4r popul\u00e4ra i Dropbox. Detta inkluderar PyCharm, Vim och VS Code. Detta har gjort processen f\u00f6r att utf\u00f6ra arbetet med annotering av kod och verifiering av dess funktionalitet betydligt enklare. Liknande \u00e5tg\u00e4rder \u00e4r vanligt f\u00f6rekommande vid annotering av befintlig kod.<\/p>\n<p>Statisk analys. Vi har skapat ett verktyg f\u00f6r att generera funktionssignaturer med hj\u00e4lp av statiska analysverktyg. Detta verktyg kan endast fungera i j\u00e4mf\u00f6relsevis enkla situationer, men det har hj\u00e4lpt oss att utan st\u00f6rre anstr\u00e4ngning \u00f6ka typbeteckningen av koden.<\/p>\n<p>St\u00f6d f\u00f6r externa bibliotek. M\u00e5nga av v\u00e5ra projekt anv\u00e4nder verktyget SQLAlchemy. Det anv\u00e4nder Python-dynamiska funktioner som typerna i PEP 484 inte kan modellera direkt. Enligt PEP 561 har vi skapat den n\u00f6dv\u00e4ndiga stub-filen och skrivit ett plugin f\u00f6r mypy.<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dropbox\/sqlalchemy-stubs\">\u00f6ppen k\u00e4llkod<\/a><\/noindex>), vilket f\u00f6rb\u00e4ttrar st\u00f6d f\u00f6r SQLAlchemy.<\/p>\n<h2>Sv\u00e5righeter vi st\u00f6tte p\u00e5<\/h2>\n<p>\nV\u00e4gen till 4 miljoner rader typad kod har inte alltid varit l\u00e4tt. P\u00e5 denna v\u00e4g har vi st\u00f6tt p\u00e5 m\u00e5nga hinder och gjort n\u00e5gra misstag. H\u00e4r \u00e4r n\u00e5gra av de problem vi st\u00f6tt p\u00e5. Vi hoppas att v\u00e5r ber\u00e4ttelse kan hj\u00e4lpa andra att undvika liknande problem.<\/p>\n<p>Saknade filer. Vi b\u00f6rjade arbetet med att kontrollera enbart ett litet antal filer. Allt som inte ingick i dessa filer kontrollerades inte. Filer lades till i kontrollistan n\u00e4r de fick sina f\u00f6rsta annotationer. Om n\u00e5got importerades fr\u00e5n en modul utanf\u00f6r kontrollomr\u00e5det, handlade det om att arbeta med v\u00e4rden av typen <code>Any<\/code>, som \u00f6verhuvudtaget inte kontrollerades. Detta ledde till en betydande f\u00f6rlust av typernas noggrannhet, s\u00e4rskilt i de tidiga migrationsstegen. Denna metod fungerade f\u00f6rv\u00e5nansv\u00e4rt bra, \u00e4ven om det ofta var s\u00e5 att till\u00e4gg av filer till kontrollomr\u00e5det visade problem p\u00e5 andra delar av kodbasen. I det v\u00e4rsta fallet, n\u00e4r tv\u00e5 isolerade kodomr\u00e5den f\u00f6renades, d\u00e4r typerna oberoende var granskade, visade det sig att typerna i dessa omr\u00e5den var of\u00f6renliga med varandra. Detta ledde till att m\u00e5nga \u00e4ndringar beh\u00f6vde g\u00f6ras i annotationerna. Nu, n\u00e4r vi ser tillbaka, f\u00f6rst\u00e5r vi att vi borde ha lagt till grundbiblioteksmodulerna i typerna f\u00f6r mypy s\u00e5 tidigt som m\u00f6jligt. Det skulle ha gjort v\u00e5rt arbete mycket mer f\u00f6ruts\u00e4gbart.<\/p>\n<p>Annotering av gammal kod. N\u00e4r vi b\u00f6rjade arbeta hade vi omkring 4 miljoner rader redan existerande Python-kod. Det stod klart att annotering av all denna kod var en tuff uppgift. Vi skapade ett verktyg kallat PyAnnotate som kan samla in typinformation under k\u00f6rning av tester och l\u00e4gga till typannoteringar i koden baserat p\u00e5 den insamlade informationen. Men vi m\u00e4rkte ingen s\u00e4rskilt utbredd anv\u00e4ndning av detta verktyg. Insamlingen av typinformation var l\u00e5ngsam, och automatiskt genererade annoteringar kr\u00e4vde ofta m\u00e5nga manuella justeringar. Vi \u00f6verv\u00e4gde att automatiskt k\u00f6ra detta verktyg vid varje kodgranskning eller att samla in typinformation baserat p\u00e5 analys av ett litet antal verkliga n\u00e4tverksf\u00f6rfr\u00e5gningar, men beslutade att inte g\u00f6ra det, eftersom n\u00e5gon av dessa metoder skulle vara f\u00f6r riskabel.<\/p>\n<p>I slut\u00e4ndan kan man konstatera att st\u00f6rsta delen av koden annoterades manuellt av dess \u00e4gare. Vi f\u00f6r att styra denna process i r\u00e4tt riktning, f\u00f6rbereder rapporter om s\u00e4rskilt viktiga moduler och funktioner som beh\u00f6ver annoteras. Till exempel \u00e4r det viktigt att f\u00f6rse biblioteksmodulen, som anv\u00e4nds p\u00e5 hundratals st\u00e4llen, med typannoteringar. Men den gamla tj\u00e4nsten som ers\u00e4tts av den nya \u00e4r inte lika viktig att annotera. Dessutom experimenterar vi med att anv\u00e4nda statisk analys f\u00f6r att generera typannoteringar f\u00f6r den gamla koden.<\/p>\n<p>Cykliska importer. Tidigare talade jag om cykliska importer (om \"beroendetrassel\"), vars existens har f\u00f6rsv\u00e5rat hastighetsoptimeringen av mypy. Vi har ocks\u00e5 f\u00e5tt arbeta h\u00e5rt f\u00f6r att ge mypy st\u00f6d f\u00f6r alla typer av idiom som orsakas av dessa cykliska importer. Nyligen avslutade vi ett stort projekt f\u00f6r att redesigna systemet, vilket \u00e5tg\u00e4rdade de flesta problem med mypy relaterade till cykliska importer. Dessa problem h\u00e4rstammade faktiskt fr\u00e5n de mycket tidiga dagarna av projektet, \u00e4nda fr\u00e5n Alore, det undervisningsspr\u00e5k som ursprungligen projektet mypy var inriktat p\u00e5. Syntaxen i Alore g\u00f6r det enkelt att hantera problem med cykliska importkommandon. Det moderna mypy har \u00e4rvt vissa begr\u00e4nsningar fr\u00e5n sin tidiga, okomplicerade implementation (som passade bra f\u00f6r Alore). Python komplicerar arbetet med cykliska importer fr\u00e4mst p\u00e5 grund av uttryckens tvetydighet. Till exempel kan en typalias faktiskt definieras under en assignmentsoperation. Mypy \u00e4r inte alltid kapabel att uppt\u00e4cka s\u00e5dana saker f\u00f6rr\u00e4n en stor del av importcykeln har behandlats. I Alore fanns det inga s\u00e5dana tvetydigheter. D\u00e5liga beslut som fattades i de tidiga utvecklingsstadierna av systemet kan \u00f6verraska programmeraren flera \u00e5r senare.<\/p>\n<h2>Sammanfattning: v\u00e4gen till 5 miljoner rader kod och nya horisonter<\/h2>\n<p>\nProjektet mypy har kommit l\u00e5ngt \u2014 fr\u00e5n tidiga prototyper till ett system som kontrollerar typerna av produktionskod best\u00e5ende av 4 miljoner rader. Under mypy:s utveckling har standardisering av typ-hints genomf\u00f6rts i Python. Idag har en stark ekosystem kring typning av Python-kod utvecklats. Det finns st\u00f6d f\u00f6r bibliotek, verktyg f\u00f6r IDE och redigerare, och flera typen kontrollerande system, var och en med sina egna f\u00f6rdelar och nackdelar.<\/p>\n<p>\u00c4ven om typkontroller redan uppfattas som en sj\u00e4lvklarhet p\u00e5 Dropbox, \u00e4r jag \u00f6vertygad om att vi fortfarande lever i gryningen av typning av Python-kod. Jag tror att teknologier f\u00f6r typkontroll kommer att forts\u00e4tta att utvecklas och f\u00f6rb\u00e4ttras.<\/p>\n<p>Om du inte har anv\u00e4nt typkontroller i ditt storskaliga Python-projekt, vet att det nu \u00e4r en utm\u00e4rkt tid att b\u00f6rja \u00f6verg\u00e5 till statisk typning. Jag har pratat med dem som gjort en s\u00e5dan \u00f6verg\u00e5ng. Ingen av dem har \u00e5ngrat det. Typkontroll g\u00f6r Python till ett spr\u00e5k som \u00e4r betydligt mer l\u00e4mpat f\u00f6r att utveckla stora projekt \u00e4n \"vanlig Python\".<\/p>\n<p><b>K\u00e4ra l\u00e4sare!<\/b> Anv\u00e4nder du typkontroller i dina Python-projekt?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"V\u00e4gen till typkontroll av 4 miljoner rader Python-kod. 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=\"V\u00e4gen till typkontroll av 4 miljoner rader Python-kod. Del 3\" src=\"\/wp-content\/uploads\/2019\/10\/098d481c25b3afaba9534c686e8f943a.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>K\u00e4lla: <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\/sv\/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=\"sv_SE\" \/>\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\/sv\/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 V\u00e4gen till typkontroll av 4 miljoner raders Python-kod. Del 3 | ProHoster","description":"Vi presenterar tredje delen av \u00f6vers\u00e4ttningen av materialet om den resa som Dropbox har genomg\u00e5tt f\u00f6r att inf\u00f6ra ett system f\u00f6r typkontroll av Python-kod.","canonical_url":"https:\/\/prohoster.info\/sv\/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":"sv_SE","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\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/38649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=38649"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/38649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/28992"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=38649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=38649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=38649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}