{"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\/es\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","title":{"rendered":"Camino hacia la verificaci\u00f3n de tipos de 4 millones de l\u00edneas de c\u00f3digo Python. Parte 3","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Les presentamos la tercera parte de la traducci\u00f3n del material sobre el camino que ha recorrido la empresa Dropbox al implementar un sistema de verificaci\u00f3n de tipos de c\u00f3digo Python.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\"><img decoding=\"async\" alt=\"Camino hacia la verificaci\u00f3n de tipos de 4 millones de l\u00edneas de c\u00f3digo Python. Parte 3\" src=\"\/wp-content\/uploads\/2019\/10\/757669265e870de604388c66adef814d.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u2192 Partes anteriores: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468233\/\">la primera<\/a><\/noindex> y <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\">la segunda<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Lograr 4 millones de l\u00edneas de c\u00f3digo tipado<\/h2>\n<p>\nOtra tarea importante (la segunda m\u00e1s mencionada en las encuestas internas) fue aumentar la cantidad de c\u00f3digo en Dropbox que estaba cubierto por verificaciones de tipos. Probamos varios enfoques para abordar este desaf\u00edo, desde el crecimiento natural de la base de c\u00f3digo tipado hasta la concentraci\u00f3n de los esfuerzos del equipo de mypy en la inferencia autom\u00e1tica de tipos est\u00e1ticos y din\u00e1micos. Al final, parec\u00eda que no hab\u00eda una estrategia ganadora simple, pero logramos un crecimiento r\u00e1pido en la cantidad de c\u00f3digo anotado al combinar m\u00faltiples enfoques.<\/p>\n<p>Como resultado, en nuestro repositorio Python m\u00e1s grande (con c\u00f3digo de backend), la cantidad de l\u00edneas de c\u00f3digo anotado alcanz\u00f3 casi 4 millones. El trabajo de tipado est\u00e1tico del c\u00f3digo se realiz\u00f3 en aproximadamente tres a\u00f1os. Mypy ahora admite varios tipos de informes sobre la cobertura del c\u00f3digo con tipos, que facilitan el seguimiento del progreso de la tipificaci\u00f3n. En particular, podemos generar informes sobre el c\u00f3digo con incertidumbres en los tipos, tales como el uso expl\u00edcito de tipo <code>Any<\/code> en las anotaciones que no se pueden verificar, o como importaciones de bibliotecas externas que carecen de anotaciones de tipo. Dentro del proyecto para mejorar la precisi\u00f3n de la verificaci\u00f3n de tipos en Dropbox, contribuimos a la mejora de las definiciones de tipos (los llamados archivos stub) para algunas bibliotecas de c\u00f3digo abierto populares en el repositorio centralizado de Python <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/python\/typeshed\">typeshed<\/a><\/noindex>.<\/p>\n<p>Implementamos (y estandarizamos en las siguientes PEP) nuevas caracter\u00edsticas del sistema de tipos que permiten el uso de tipos m\u00e1s precisos para ciertos patrones espec\u00edficos de Python. Un ejemplo notable de esto es <code>TypeDict<\/code>, que proporciona tipos para diccionarios similares a JSON que tienen un conjunto fijo de claves de tipo cadena, cada una con su propio tipo de valor. Continuaremos expandiendo el sistema de tipos. Probablemente, nuestro pr\u00f3ximo paso ser\u00e1 mejorar el soporte para las capacidades de Python en el manejo de n\u00fameros.<\/p>\n<p><img decoding=\"async\" alt=\"Camino hacia la verificaci\u00f3n de tipos de 4 millones de l\u00edneas de c\u00f3digo Python. Parte 3\" src=\"\/wp-content\/uploads\/2019\/10\/297b9e823141d6cb0d2f19f9a78a1153.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>N\u00famero de l\u00edneas de c\u00f3digo anotado: servidor<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Camino hacia la verificaci\u00f3n de tipos de 4 millones de l\u00edneas de c\u00f3digo Python. Parte 3\" src=\"\/wp-content\/uploads\/2019\/10\/c183a9227e51d847bfdb2b8f6153684f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>N\u00famero de l\u00edneas de c\u00f3digo anotado: cliente<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Camino hacia la verificaci\u00f3n de tipos de 4 millones de l\u00edneas de c\u00f3digo Python. Parte 3\" src=\"\/wp-content\/uploads\/2019\/10\/0a8b936fa454a34c09a9c6a2694485c9.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>N\u00famero total de l\u00edneas de c\u00f3digo anotado<\/i><\/p>\n<p>Aqu\u00ed tienes un resumen de las caracter\u00edsticas principales de las acciones que hemos llevado a cabo para aumentar la cantidad de c\u00f3digo anotado en Dropbox:<\/p>\n<p>Rigor en la anotaci\u00f3n. Hemos ido aumentando gradualmente los requisitos de rigor para la anotaci\u00f3n de nuevo c\u00f3digo. Comenzamos con consejos de linters que suger\u00edan a\u00f1adir anotaciones en archivos que ya conten\u00edan algunas anotaciones. Ahora exigimos la presencia de anotaciones de tipos en nuevos archivos de Python y en la mayor\u00eda de los archivos existentes.<\/p>\n<p>Informes de tipado. Enviamos semanalmente a los equipos informes sobre el nivel de tipado de su c\u00f3digo y les damos consejos acerca de qu\u00e9 deber\u00eda ser anotado primero.<\/p>\n<p>Promoci\u00f3n de mypy. Hablamos sobre mypy en diversos eventos y nos comunicamos con los equipos, ayud\u00e1ndoles a comenzar a utilizar anotaciones de tipos.<\/p>\n<p>Encuestas. Realizamos encuestas peri\u00f3dicas a los usuarios para identificar los principales problemas. Estamos dispuestos a ir lo suficientemente lejos para resolver estos problemas (incluso hasta el punto de crear un nuevo lenguaje para acelerar mypy!).<\/p>\n<p>Rendimiento. Hemos mejorado significativamente el rendimiento de mypy gracias al uso de un demonio y mypyc. Esto se hizo para suavizar las molestias que surgen durante el proceso de anotaci\u00f3n y para permitir trabajar con grandes vol\u00famenes de c\u00f3digo.<\/p>\n<p>Integraci\u00f3n con editores. Creamos herramientas para soportar la ejecuci\u00f3n de mypy en los editores que son populares en Dropbox. Esto incluye PyCharm, Vim y VS Code. Esto ha simplificado considerablemente el proceso de realizar trabajos de anotaci\u00f3n de c\u00f3digo y de verificar su funcionalidad. Estas acciones son habituales cuando se anota c\u00f3digo existente.<\/p>\n<p>An\u00e1lisis est\u00e1tico. Creamos una herramienta para extraer firmas de funciones utilizando t\u00e9cnicas de an\u00e1lisis est\u00e1tico. Esta herramienta puede funcionar solo en situaciones relativamente simples, pero nos ayud\u00f3 a aumentar la cobertura del c\u00f3digo con tipos sin grandes esfuerzos.<\/p>\n<p>Soporte para bibliotecas de terceros. En muchos de nuestros proyectos utilizamos un conjunto de herramientas de SQLAlchemy. Este aplica las capacidades din\u00e1micas de Python, que los tipos PEP 484 no pueden modelar directamente. Hemos creado un archivo stub correspondiente y escrito un plugin para mypy, de acuerdo con PEP 561,<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dropbox\/sqlalchemy-stubs\">de c\u00f3digo abierto<\/a><\/noindex>), que mejora el soporte de SQLAlchemy.<\/p>\n<h2>Dificultades que encontramos<\/h2>\n<p>\nEl camino hacia 4 millones de l\u00edneas de c\u00f3digo tipificado no siempre fue f\u00e1cil. En este trayecto nos encontramos con varios baches y cometimos varios errores. Aqu\u00ed hay algunos de los problemas que enfrentamos. Esperamos que contar sobre ellos ayude a otros a evitar problemas similares.<\/p>\n<p>Archivos faltantes. Comenzamos a trabajar con la revisi\u00f3n de un n\u00famero peque\u00f1o de archivos. Todo lo que no estaba en el conjunto de estos archivos no se revisaba. Los archivos se a\u00f1ad\u00edan a la lista de revisi\u00f3n cuando aparec\u00edan las primeras anotaciones. Si se importaba algo de un m\u00f3dulo ubicado fuera del \u00e1mbito de revisi\u00f3n, se trataba de trabajar con valores de tipo <code>Any<\/code>, que no se revisaban en absoluto. Esto llev\u00f3 a una p\u00e9rdida significativa de precisi\u00f3n en la tipificaci\u00f3n, especialmente en las primeras etapas de la migraci\u00f3n. Este enfoque funcion\u00f3 sorprendentemente bien, aunque era t\u00edpico que a\u00f1adir archivos al \u00e1mbito de revisi\u00f3n descubriera problemas en otras partes de la base de c\u00f3digo. En el peor de los casos, cuando se un\u00edan dos \u00e1reas de c\u00f3digo aisladas, en las que las tipificaciones se verificaron de forma independiente, resultaba que los tipos de estas \u00e1reas eran incompatibles entre s\u00ed. Esto llevaba a la necesidad de realizar muchos cambios en las anotaciones. Ahora, mirando hacia atr\u00e1s, entendemos que debimos a\u00f1adir a la revisi\u00f3n de tipos mypy los m\u00f3dulos de biblioteca base tan pronto como fuera posible. Esto habr\u00eda hecho nuestro trabajo mucho m\u00e1s predecible.<\/p>\n<p>Anotaci\u00f3n del c\u00f3digo antiguo. Cuando comenzamos a trabajar, ten\u00edamos alrededor de 4 millones de l\u00edneas de c\u00f3digo Python existente. Era claro que anotar todo ese c\u00f3digo era una tarea dif\u00edcil. Creamos una herramienta llamada PyAnnotate, que puede recolectar informaci\u00f3n sobre tipos durante la ejecuci\u00f3n de pruebas y puede agregar anotaciones de tipos al c\u00f3digo, bas\u00e1ndose en la informaci\u00f3n recolectada. Sin embargo, no notamos una adopci\u00f3n especialmente amplia de esta herramienta. La recolecci\u00f3n de informaci\u00f3n sobre tipos era lenta, y las anotaciones generadas autom\u00e1ticamente a menudo requer\u00edan muchas correcciones manuales. Pensamos en ejecutar autom\u00e1ticamente esta herramienta en cada verificaci\u00f3n de c\u00f3digo, o en recolectar informaci\u00f3n sobre tipos bas\u00e1ndonos en el an\u00e1lisis de un peque\u00f1o volumen de solicitudes reales de la red, pero decidimos no hacerlo, ya que cualquiera de estos enfoques era demasiado arriesgado.<\/p>\n<p>Como conclusi\u00f3n, se puede se\u00f1alar que la mayor parte del c\u00f3digo fue anotado manualmente por sus propietarios. Para guiar este proceso en la direcci\u00f3n correcta, preparamos informes sobre m\u00f3dulos y funciones especialmente importantes que deben ser anotados. Por ejemplo, es crucial proporcionar anotaciones de tipos para el m\u00f3dulo de biblioteca que se utiliza en cientos de lugares. En cambio, anotar un servicio antiguo que est\u00e1 siendo reemplazado por uno nuevo no es tan importante. Adem\u00e1s, estamos experimentando con el uso de an\u00e1lisis est\u00e1tico para generar anotaciones de tipos para el c\u00f3digo antiguo.<\/p>\n<p>Importaciones c\u00edclicas. Anteriormente mencion\u00e9 las importaciones c\u00edclicas (los \"enredos de dependencias\"), cuya existencia complic\u00f3 la aceleraci\u00f3n de mypy. Adem\u00e1s, tuvimos que trabajar seriamente para dotar a mypy de soporte para todos los tipos de idiom\u00e1ticas, cuya causa son estas importaciones c\u00edclicas. Recientemente completamos un gran proyecto de redise\u00f1o del sistema, que solucion\u00f3 la mayor\u00eda de los problemas de mypy relacionados con las importaciones c\u00edclicas. Estos problemas, de hecho, se originaron en los primeros d\u00edas del proyecto, incluso en Alore, el lenguaje educativo para el cual originalmente se dise\u00f1\u00f3 mypy. La sintaxis de Alore permite resolver f\u00e1cilmente los problemas de los comandos de importaci\u00f3n c\u00edclicos. El mypy moderno hered\u00f3 algunas limitaciones de su primera implementaci\u00f3n rudimentaria (que era adecuada para Alore). Python complica el trabajo con importaciones c\u00edclicas principalmente debido a la ambig\u00fcedad de las expresiones. Por ejemplo, durante una operaci\u00f3n de asignaci\u00f3n de valores, un alias de tipo puede ser determinado. Mypy no siempre puede detectar tales cosas hasta que gran parte del ciclo de importaci\u00f3n haya sido procesada. En Alore no hab\u00eda tales ambig\u00fcedades. Las decisiones desafortunadas tomadas en los primeros d\u00edas de desarrollo del sistema pueden presentar al programador una sorpresa desagradable muchos a\u00f1os despu\u00e9s.<\/p>\n<h2>Conclusiones: el camino hacia 5 millones de l\u00edneas de c\u00f3digo y nuevos horizontes<\/h2>\n<p>\nEl proyecto mypy ha recorrido un largo camino, desde los primeros prototipos hasta un sistema que controla los tipos de c\u00f3digo de producci\u00f3n que abarca 4 millones de l\u00edneas. A medida que mypy ha evolucionado, se ha estandarizado las sugerencias de tipos en Python. Hoy en d\u00eda, ha surgido un ecosistema robusto en torno a la tipificaci\u00f3n del c\u00f3digo Python. Hay soporte para bibliotecas, herramientas auxiliares para IDE y editores, y existen varios sistemas de control de tipos, cada uno con sus ventajas y desventajas.<\/p>\n<p>A pesar de que la verificaci\u00f3n de tipos ya se considera por defecto en Dropbox, estoy convencido de que a\u00fan estamos en los inicios de la tipificaci\u00f3n del c\u00f3digo Python. Creo que las tecnolog\u00edas de verificaci\u00f3n de tipos seguir\u00e1n desarroll\u00e1ndose y mejorando.<\/p>\n<p>Si a\u00fan no has utilizado las verificaciones de tipos en tu proyecto de Python a gran escala, considera que ahora es un momento muy adecuado para comenzar la transici\u00f3n hacia la tipificaci\u00f3n est\u00e1tica. He hablado con quienes han realizado esta transici\u00f3n, y nadie se ha arrepentido. El control de tipos convierte a Python en un lenguaje que se adapta mucho mejor para el desarrollo de grandes proyectos que el 'Python com\u00fan'.<\/p>\n<p><b>\u00a1Estimados lectores!<\/b> \u00bfUtilizas el control de tipos en tus proyectos de Python?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Camino hacia la verificaci\u00f3n de tipos de 4 millones de l\u00edneas de c\u00f3digo Python. Parte 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=\"Camino hacia la verificaci\u00f3n de tipos de 4 millones de l\u00edneas de c\u00f3digo Python. Parte 3\" src=\"\/wp-content\/uploads\/2019\/10\/098d481c25b3afaba9534c686e8f943a.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Fuente: <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.2 - 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\/es\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\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\/es\/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\udd47El camino hacia la verificaci\u00f3n de tipos en 4 millones de l\u00edneas de c\u00f3digo Python. Parte 3 | ProHoster","description":"Les presentamos la tercera parte de la traducci\u00f3n del material sobre el camino que ha recorrido la empresa Dropbox al implementar un sistema de verificaci\u00f3n de tipos de c\u00f3digo Python.","canonical_url":"https:\/\/prohoster.info\/es\/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":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/38649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=38649"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/38649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/28992"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=38649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=38649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=38649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}