{"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\/it\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-2","title":{"rendered":"Il percorso per la verifica dei tipi di 4 milioni di righe di codice Python. Parte 2","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Oggi pubblichiamo la seconda parte della traduzione riguardante come Dropbox ha organizzato il controllo dei tipi di diversi milioni di righe di codice Python.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\"><img decoding=\"async\" alt=\"Il percorso per la verifica dei tipi di 4 milioni di righe di codice Python. Parte 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\/\">Leggi la prima parte<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Supporto ufficiale per i tipi (PEP 484)<\/h2>\n<p>\nAbbiamo condotto i primi esperimenti significativi con mypy in Dropbox durante la Hack Week del 2014. La Hack Week \u00e8 un evento che si svolge in Dropbox per una settimana. In questo periodo, i dipendenti possono lavorare su qualsiasi progetto! Alcuni dei progetti tecnologici pi\u00f9 celebri di Dropbox sono iniziati proprio durante questi eventi. Da questo esperimento, abbiamo concluso che mypy sembra promettente, sebbene questo progetto non fosse ancora pronto per un uso su larga scala.<\/p>\n<p>All'epoca circolava l'idea di standardizzare i sistemi di suggerimenti per i tipi Python. Come ho gi\u00e0 detto, a partire da Python 3.0 era possibile utilizzare le annotazioni dei tipi per le funzioni, ma erano solo espressioni arbitrarie, senza una sintassi e una semantica definiti. Durante l'esecuzione del programma, queste annotazioni venivano per lo pi\u00f9 semplicemente ignorate. Dopo il Hack Week, abbiamo iniziato a lavorare sulla standardizzazione della semantica. Questo lavoro ha portato alla nascita <noindex><a rel=\"nofollow\" href=\"https:\/\/www.python.org\/dev\/peps\/pep-0484\/\">PEP 484<\/a><\/noindex> (questo documento \u00e8 stato sviluppato in collaborazione tra Guido van Rossum, \u0141ukasz Lange e me).<\/p>\n<p>Le nostre motivazioni possono essere interpretate da due prospettive. In primo luogo, speravamo che l'intero ecosistema Python potesse adottare un approccio comune all'uso dei suggerimenti sui tipi (type hints \u2014 un termine usato in Python come equivalente delle \u201cannotazioni di tipo\u201d). Considerate i rischi potenziali, ci\u00f2 sarebbe stato preferibile rispetto all'uso di molteplici approcci incompatibili tra loro. In secondo luogo, volevamo discutere apertamente meccanismi di annotazione dei tipi con molti membri della comunit\u00e0 Python. In parte, questo desiderio nasceva dal fatto che non volevamo apparire come \u00aberetici\u00bb rispetto alle idee fondamentali del linguaggio agli occhi di un vasto pubblico di programmatori Python. Si tratta di un linguaggio tipizzato dinamicamente, noto per la sua \u00abtipizzazione anatra\u00bb. All'inizio, nella comunit\u00e0, c'era una certa diffidenza verso l'idea della tipizzazione statica. Tuttavia, tale atteggiamento alla fine si \u00e8 attenuato \u2014 dopo che \u00e8 diventato chiaro che la tipizzazione statica non sarebbe stata resa obbligatoria (e dopo che le persone hanno capito che era davvero utile).<\/p>\n<p>La sintassi adottata alla fine per i suggerimenti sui tipi era molto simile a quella supportata da mypy all'epoca. Il documento PEP 484 \u00e8 stato rilasciato insieme a Python 3.5 nel 2015. Python non era pi\u00f9 un linguaggio che supportava solo la tipizzazione dinamica. Mi piace pensare a questo evento come a una tappa significativa nella storia di Python.<\/p>\n<h2>Inizio della migrazione<\/h2>\n<p>\nAlla fine del 2015, in Dropbox, per lavorare su mypy, \u00e8 stato creato un team di tre persone. Composto da Guido van Rossum, Greg Price e David Fisher, questo \u00e8 stato l'inizio di un rapido sviluppo. Il primo ostacolo alla crescita di mypy \u00e8 stata la performance. Come ho accennato in precedenza, all'inizio dello sviluppo del progetto, stavo pensando di portare l'implementazione di mypy nel linguaggio C, ma questa idea \u00e8 stata temporaneamente scartata. Ci siamo trovati bloccati con l'interprete CPython, che non era sufficientemente veloce per strumenti come mypy. (Il progetto PyPy, un'implementazione alternativa di Python con compilatore JIT, non ci ha aiutato.)<\/p>\n<p>Fortunatamente, siamo stati aiutati da alcuni miglioramenti algoritmici. La prima potente \"accelerazione\" \u00e8 stata l'implementazione del controllo incrementale. L'idea di questo miglioramento era semplice: se tutte le dipendenze del modulo non erano cambiate dall'ultima esecuzione di mypy, potevamo utilizzare, durante il lavoro con le dipendenze, i dati memorizzati nella cache durante la sessione precedente. Dobbiamo solo eseguire il controllo dei tipi nei file modificati e in quelli che dipendono da essi. Mypy \u00e8 andato anche oltre: se l'interfaccia esterna del modulo non era cambiata, mypy presumeva che non fosse necessario controllare di nuovo gli altri moduli che importano questo modulo.<\/p>\n<p>Il controllo incrementale ci ha aiutato molto nell'annotazione di grandi volumi di codice esistente. Infatti, questo processo di solito comporta numerosi avvii iterativi di mypy, poich\u00e9 le annotazioni vengono aggiunte gradualmente al codice e migliorate progressivamente. La prima esecuzione di mypy era comunque molto lenta, dato che doveva verificare molte dipendenze. Per migliorare la situazione, abbiamo implementato un meccanismo di caching remoto. Se mypy rileva che la cache locale \u00e8 probabilmente obsoleta, carica l'attuale istantanea della cache per l'intera base di codice da un repository centralizzato. Quindi, esegue un controllo incrementale utilizzando questa istantanea. Questo ci ha spostati ulteriormente verso un aumento delle prestazioni di mypy.<\/p>\n<p>\u00c8 stato un periodo di rapida e naturale introduzione del sistema di controllo dei tipi in Dropbox. Entro la fine del 2016, avevamo circa 420.000 righe di codice Python con annotazioni di tipo. Molti utenti hanno accolto con entusiasmo il controllo dei tipi. In Dropbox, mypy \u00e8 stato utilizzato da un numero crescente di squadre di sviluppatori.<\/p>\n<p>Allora sembrava andare bene, ma avevamo ancora molto da fare. Iniziammo a condurre sondaggi interni periodici per identificare i punti critici del progetto e capire quali problemi affrontare per primi (questa pratica \u00e8 utilizzata in azienda ancora oggi). Le due questioni pi\u00f9 importanti, come si \u00e8 rivelato, erano chiare. Prima di tutto, era necessario un maggiore copertura del codice con i tipi, in secondo luogo, era fondamentale che mypy funzionasse pi\u00f9 velocemente. Era evidente che il nostro lavoro per velocizzare mypy e integrarlo nei progetti dell'azienda era ancora lontano dal suo completamento. Consapevoli dell'importanza di questi due compiti, ci siamo messi al lavoro per risolverli.<\/p>\n<h2>Pi\u00f9 prestazioni!<\/h2>\n<p>\nI controlli incrementali hanno velocizzato mypy, ma questo strumento era ancora lontano dall'essere sufficientemente veloce. Molti controlli incrementali duravano circa un minuto. La causa di ci\u00f2 erano gli import ciclici. Questo probabilmente non sorprende chi ha mai lavorato con grandi basi di codice scritte in Python. Avevamo set composti da centinaia di moduli, ognuno dei quali importava indirettamente tutti gli altri. Se qualsiasi file nel ciclo di importazioni veniva modificato, mypy doveva elaborare tutti i file coinvolti in quel ciclo e spesso anche eventuali moduli che importavano moduli da quel ciclo. Uno di questi cicli era il famigerato \"nodo delle dipendenze\", che ha causato molti problemi in Dropbox. Una volta questa struttura conteneva diverse centinaia di moduli, ed era importata, direttamente o indirettamente, da molti test e utilizzata anche nel codice di produzione.<\/p>\n<p>Abbiamo preso in considerazione la possibilit\u00e0 di \"disambiguare\" le dipendenze cicliche, ma non avevamo le risorse per farlo. C'era troppo codice con cui non eravamo familiari. Alla fine, abbiamo optato per un approccio alternativo. Abbiamo deciso di far funzionare mypy rapidamente anche in presenza di \"matasse di dipendenze\". Abbiamo raggiunto questo obiettivo utilizzando un demone mypy. Il demone \u00e8 un processo server che implementa due interessanti funzionalit\u00e0. Innanzitutto, mantiene in memoria informazioni su tutta la base di codice. Questo significa che ad ogni avvio di mypy non \u00e8 necessario caricare i dati cache riguardanti migliaia di dipendenze importate. In secondo luogo, analizza con attenzione, a livello di piccole unit\u00e0 strutturali, le dipendenze tra funzioni e altre entit\u00e0. Ad esempio, se una funzione <code>foo<\/code> chiama la funzione <code>bar<\/code>, allora esiste una dipendenza <code>foo<\/code> da <code>bar<\/code>. Quando un file viene modificato, il demone elabora inizialmente solo il file cambiato in isolamento. Poi esamina le modifiche di quel file che sono visibili dall'esterno, come le firme delle funzioni che sono cambiate. Il demone utilizza informazioni dettagliate sulle importazioni solo per ri-verificare le funzioni che utilizzano realmente la funzione modificata. Di solito, con questo approccio, \u00e8 necessario verificare solo poche funzioni.<\/p>\n<p>Realizzare tutto ci\u00f2 non \u00e8 stato semplice, poich\u00e9 l'implementazione originale di mypy era fortemente orientata al trattamento di un solo file alla volta. Abbiamo dovuto affrontare numerosi casi limite, la cui occorrenza richiedeva ripetute verifiche quando qualcosa nel codice veniva cambiato. Ad esempio, accade quando a una classe viene assegnata una nuova classe base. Dopo aver completato ci\u00f2 che volevamo, siamo riusciti a ridurre il tempo di esecuzione della maggior parte dei controlli incrementali a pochi secondi. Questo ci \u00e8 sembrato un grande successo.<\/p>\n<h2>Ancora pi\u00f9 prestazioni!<\/h2>\n<p>\nInsieme alla caching remoto di cui ho parlato sopra, il demone mypy ha praticamente risolto gran parte dei problemi che si presentavano quando un programmatore eseguiva frequentemente il controllo dei tipi apportando modifiche a un numero limitato di file. Tuttavia, le prestazioni del sistema, nel peggiore dei casi, erano ancora lontane dall'ottimale. Un avvio pulito di mypy poteva richiedere pi\u00f9 di 15 minuti. E questo era decisamente pi\u00f9 di quanto avremmo gradito. Ogni settimana la situazione peggiorava, poich\u00e9 i programmatori continuavano a scrivere nuovo codice e ad aggiungere annotazioni al codice esistente. I nostri utenti desideravano ancora maggiore performance e noi eravamo pronti ad andare incontro alle loro esigenze.<\/p>\n<p>Abbiamo deciso di tornare a una delle idee iniziali riguardo a mypy. In particolare, alla trasformazione del codice Python in codice C. Gli esperimenti con Cython (un sistema che permette di tradurre codice scritto in Python in codice C) non ci hanno fornito alcun miglioramento visibile, quindi abbiamo deciso di riscoprire l'idea di scrivere un nostro compilatore. Poich\u00e9 la base di codice di mypy (scritta in Python) conteneva gi\u00e0 tutte le annotazioni di tipo necessarie, ci \u00e8 sembrato valido tentare di utilizzare queste annotazioni per migliorare le prestazioni del sistema. Ho rapidamente creato un prototipo per testare questa idea. Ha mostrato un aumento delle prestazioni superiore a dieci volte in vari micro-benchmark. La nostra idea era di compilare moduli Python in moduli C utilizzando Cython e di trasformare le annotazioni di tipo in controlli di tipo effettuati durante l'esecuzione del programma (di solito, le annotazioni di tipo vengono ignorate durante l'esecuzione dei programmi e sono utilizzate solo dai sistemi di controllo dei tipi). In effetti, stavamo pianificando di tradurre l'implementazione di mypy da Python a un linguaggio che fosse staticamente tipizzato, che apparisse (e, per la maggior parte, funzionasse) esattamente come Python. (Questa forma di migrazione tra linguaggi \u00e8 diventata una sorta di tradizione per il progetto mypy. L'implementazione originale di mypy \u00e8 stata scritta in Alore, poi c'\u00e8 stata una ibridazione sintattica tra Java e Python).<\/p>\n<p>L'orientamento sull'API delle estensioni CPython \u00e8 stato fondamentale per non perdere opportunit\u00e0 nella gestione del progetto. Non abbiamo dovuto implementare una macchina virtuale o librerie di cui aveva bisogno mypy. Inoltre, avremmo comunque avuto accesso all'intero ecosistema Python, con a disposizione tutti gli strumenti (come pytest). Ci\u00f2 significava che avremmo potuto continuare a utilizzare codice Python interpretato durante lo sviluppo, consentendoci di lavorare con una rapida modifica e test del codice, senza dover aspettare la compilazione. Sembra che siamo riusciti, per cos\u00ec dire, a stare su due sedie contemporaneamente, e questa situazione ci piaceva.<\/p>\n<p>Il compilatore che abbiamo chiamato mypyc (poich\u00e9 utilizza mypy per l'analisi dei tipi come frontend) si \u00e8 rivelato un progetto molto riuscito. In generale, abbiamo ottenuto un incremento di circa quattro volte nella velocit\u00e0 di esecuzione frequente di mypy senza l'uso di caching. Lo sviluppo del nucleo del progetto mypyc ha richiesto al piccolo team composto da Michael Sullivan, Ivan Levkyvsky, Hugh Han e me circa 4 mesi di calendario. Questo lavoro \u00e8 stato decisamente meno complesso di quanto sarebbe stato necessario per riscrivere mypy, ad esempio, in C++ o Go. Inoltre, i cambiamenti che abbiamo dovuto apportare al progetto sono stati notevolmente minori di quelli che avremmo dovuto fare riscrivendolo in un'altra lingua. Inoltre, speravamo di portare mypyc a un livello tale che altri programmatori di Dropbox potessero utilizzarlo per compilare e accelerare il proprio codice.<\/p>\n<p>Per raggiungere un livello di performance simile, abbiamo dovuto adottare alcune soluzioni ingegneristiche interessanti. Ad esempio, il compilatore pu\u00f2 accelerare l'esecuzione di molte operazioni grazie all'uso di strutture C rapide e a basso livello. Un invocazione di una funzione compilata viene tradotta in una chiamata di funzione C, e tale invocazione \u00e8 notevolmente pi\u00f9 veloce rispetto a quella di una funzione interpretata. Alcune operazioni, come la ricerca nei dizionari, continuavano a utilizzare normali chiamate all'API C di CPython, che dopo la compilazione si rivelavano solo leggermente pi\u00f9 veloci. Siamo riusciti a eliminare l'onere aggiuntivo sulla sistema causato dall'interpretazione, ma questo ha portato soltanto a un modesto guadagno in termini di prestazioni.<\/p>\n<p>Per identificare le operazioni pi\u00f9 comuni considerate \"lente\", abbiamo eseguito il profiling del codice. Armati dei dati ottenuti, abbiamo cercato di \"ottimizzare\" mypyc affinch\u00e9 generasse codice C pi\u00f9 veloce per tali operazioni, oppure di riscrivere il codice Python corrispondente utilizzando operazioni pi\u00f9 veloci (e a volte non avevamo semplicemente una soluzione facile per un determinato problema). Riscrivere il codice Python si \u00e8 frequentemente rivelato essere una soluzione pi\u00f9 semplice rispetto all'implementazione dell'esecuzione automatica della stessa trasformazione nel compilatore. A lungo termine, volevamo automatizzare molte di queste trasformazioni, ma in quel momento eravamo focalizzati su come velocizzare mypy con il minimo sforzo. E mentre perseguivamo questo obiettivo, abbiamo preso alcune scorciatoie.<\/p>\n<p>Continua...<\/p>\n<p><b>Gentili lettori!<\/b> Quali impressioni ti ha suscitato il progetto mypy quando hai scoperto la sua esistenza?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Il percorso per la verifica dei tipi di 4 milioni di righe di codice Python. Parte 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=\"Il percorso per la verifica dei tipi di 4 milioni di righe di codice Python. Parte 2\" src=\"\/wp-content\/uploads\/2019\/09\/263173dd3ab487da330ff9063e3c180e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Fonte: <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\/it\/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=\"it_IT\" \/>\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\/it\/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\udd47 Il percorso per la verifica dei tipi di 4 milioni di righe di codice Python. Parte 2 | ProHoster","description":"Oggi pubblichiamo la seconda parte della traduzione del materiale su come Dropbox ha organizzato il controllo dei tipi per milioni di righe di codice Python. \u2192 Leggi la prima parte Supporto ufficiale dei tipi (PEP 484) Abbiamo effettuato i primi esperimenti significativi con mypy in Dropbox durante la Hack Week 2014. La Hack Week \u00e8 un evento organizzato da Dropbox che dura una settimana. Durante questo periodo","canonical_url":"https:\/\/prohoster.info\/it\/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":"it_IT","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\/it\/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\/it\/wp-json\/wp\/v2\/posts\/38479","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=38479"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/38479\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/28879"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=38479"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=38479"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=38479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}