Tipificación estática en Python 3.9


#1

Jordi Contestí

Abstract:
Aunque Python es un lenguaje con tipificación dinámica, desde hace tiempo tenemos la posibilidad de utilizar tipificación estática de forma opcional. De esta forma, en la futura versión 3.9 las funcionalidades asociadas a la tipificación estática van a ampliarse. En esta charla explicaremos qué nos ofrecerá la tipificación estática al completo en la versión 3.9 mediante ejemplos de código, daremos recomendaciones sobre su uso y veremos estrategias para introducirla en nuestro código.

Bio:
Ingeniero en Informática, Máster en Business Intelligence y Big Data y actualmente Head of Data en Habitissimo.


#2

Hola:

Escribo en este comentario las principales referencias que he utilizado para preparar la charla, por si queréis seguir profundizando en la tipificación estática:

Y algunas charlas para aprender más sobre este tema:

Saludos :grinning:


#3

Hola! Me ha dado la sensación de que mypy es una especie de linter, ¿pylint no haría una función parecida?


#4

Gracias por la charla. ¿Supone una mejora de rendimiento?


#5

Parece ser que mypy se encarga solo de los tipos, así que diría que puede considerarse más un complemento a pylint, al menos si este último no tiene soporte ya para el tipo.


#6

Hola Jordi,

Enhorabuena por tu charla! Me ha resultado muy interesante.
¿Sabes si existe alguna herramienta que te permita tipificar código ya escrito automáticamente?
Algo que al menos te pueda hacer una primera aproximación…


#7

En relación con la pregunta de @andros

¿Has probado Mypyc? ¿Crees que algún día Cython hará uso de forma eficiente de los tipos de Python (algo parecido a lo que hace numba ‘intentando adivinar’ tipos)?


#8

¿Algún artículo en el que se hable de los diferentes comprobadores de tipado estático, sus diferencias y cuál puede convenir usar en cada caso?

¿Crees que en algún momento puede llegar a incorporarse un comprobador oficial en la biblioteca estándar, tal como ha ocurrido con otros módulos en Python?


#9

Muy interesante. Es una pena que, por ahora, solo valga como documentación y base para herramientas externas. Yo creo que, aunque no se haga exactamente en tiempo de ejecución, sería incluso más potente e interesante si las restricciones del tipado se compilaran a bytecode (véase al importar un archivo en otro) y se aplicaran en el resto del código.


#10

Hola, gracias por tu pregunta, @andros.

Pues no supone una mejora de rendimiento, puesto que en tiempo de ejecución todas las declaraciones de tipos se ignoran :frowning:

Sobre el rendimiento en Python, que es algo que siempre ha preocupado a la comunidad, yo la verdad es que no creo que sea tan importante. Durante muchos años estuve trabajando con Java y allí también se tiene la misma preocupación: que el código no es suficientemente rápido. A ver, en realidad, ¿cuántas veces necesitamos que el código sea tan rápido como para cumplir con los requisitos de nuestro proyecto o aplicación? Seguro que si lo pensamos nos daremos cuenta que no es habitual. Y además, la mejora del rendimiento siempre va en detrimento de otras cosas… por ejemplo, en Data Science se habla mucho de utilizar Julia en lugar de Python porque es mucho más rápido, pero después te das cuenta que si programas en Julia tendrás que esperar a que el código se compile y cada vez que cambies una línea, tendrás que compilarlo otra vez. Y si tienes un PC como el que tengo yo, que no está mal pero no es nada del otro mundo, entonces lo que ganamos en tiempo de ejecución lo perdemos en tiempo de construcción del código.

Otro tema es que sí parece posible utilizar las declaraciones de tipo en Python para mejorar el rendimiento, porque el código resultante es muy similar al que tendríamos en un lenguaje como C (por la tipificación estática, claro). En mypy hay subproyecto llamado mypyc (creo que antes era un proyecto de Dropbox). Yo no lo he utilizado nunca, la vedad. En mi experiencia personal he usado los tipos para mejorar la calidad del código, no con el objetivo de mejorar el rendimiento.

Saludos.


#11

@jmmedina y @mgmacias95: sí, mypy funciona como un linter, pero está destinado únicamente a la verificación de la parte del código destinada a la tipificación estática. Lo ideal sería utilizar ambos en nuestro proyecto si tenemos tipificación estática, desde mi punto de vista.


#12

Qué buena pregunta, @eduherraiz, pues ni idea, la verdad. Es algo que no me había planteado :slight_smile:.


#13

PyType (de google) te hace inferencia de tipos:

Me suena que hubiera otro pero ahora no lo encuentro.

EDIT: PyAnnotate de Dropbox: https://github.com/dropbox/pyannotate


#14

Hola, @kikocorreoso, pues no he probado mypyc, la verdad. Cuando he utilizado la tipificación estática en Python ha sido con el objetivo de mejorar la calidad del código y no para mejorar el rendimiento. Recuerdo haber seguido alguna charla sobre mypyc y parece que todavía no estaría tan maduro como para poder usarlo en proyectos (serios) en producción.

La teoría dice que sí que es posible usar estos tipos para obtener una ejecución más eficiente. Ahora bien, el hecho de que en Python tengamos tipificación estática opcional, quizá lo más lógico sería obligar a que todo el proyecto tenga tipificación estática y de esta forma tendríamos un código tipificado tal como lo tenemos en otros lenguajes como Java, C, etc…, lo que en mi opinón facilitaría el trabajo de mejorar el rendimiento del proyecto mediante una herramienta como mypyc.

Saludos :slight_smile:


#15

Hola, @dukebody, precisamente es algo que busqué para preparar la charla y no lo encontré. Mi sensación es que la tipificación estática no está muy extendida, la verdad, y al ver que no había ni muchos artículos ni muchas charlas decidí proponer una charla en este sentido.

Incluso hay personas que opinan que añadir tipificación estática a un lenguaje como Python es una especie de sacrilegio :slight_smile: . Yo en cambio pienso que es una solución fantástica para atraer a programadores/as de otros lenguajes estáticos con preocupación por perder el control de los tipos al pasar a Python… yo sinceramente viniendo de Java cuando empecé con Python es lo primero que me asustó.

Sobre todos los comprobadores que tenemos disponibles, creo que como comunidad nos hemos equivocado al no apostar por un único proyecto, por ejemplo, mypy (o el que sea, claro), porque en realidad no tiene mucho sentido que tengamos tantas alternativas. Es cierto que no todos los proyectos hacen lo mismo, pero si algo bueno tenemos en Python actualmente comparado con otras comunidades como JavaScript por ejemplo es que la comunidad Python es mucho más colaborativa y participativa, lo que impide que haya cientos de opciones para hacer lo mismo.

Para preparar las charlas me leí todos los PEP asociados (para mí preparar una charla es aprender) y si algo queda claro es que Python seguirá siendo siempre un lenguaje dinámico. Seguro que si se añade algún comprobador oficial será mypy, o casi seguro porque nunca se sabe, pero es algo que no he leído en ningún lugar. Ahora mismo que mypy no esté sincronizado con Python 3.9 también es significativo: faltan manos en mypy para que avance y mantenerlo (¿algún volutario/a por aquí? :smile:), por lo que si se integra como comprobador oficial obligaría a sincronizarlo completamente con las versiones de Python, con el consiguiente trabajo añadido.

Saludos :blush:


#16

Sí, yo estoy de acuerdo, @jmmedina :slight_smile:


#17

Hola Jordi!

Muchas gracias por tu charla, muy interesante!!

Acabo de hacer una prueba en un proyecto que tengo y me he dado cuenta de que aparentemente no hay una manera fácil de indicarle a mypy que compruebe también todos los sub-directorios. Lo he intentado pasandole source/*, source/**/*.py, etc., pero nada.

Sabes si hay alguna manera? Y si no, sabes si uno de los demás paquetes que mencionas ofrece esa posibilidad?

Gra6!


#18

Pasándole el nombre de la carpeta:

https://mypy.readthedocs.io/en/stable/running_mypy.html


#19

Gracias por tu respuesta @kikocorreoso! El problema es que indicando la carpeta sólo se ejecuta sobre los ficheros en esa misma carpeta, no sobre ficheros en sub-carpetas como source/infrastructure o source/infrastructure/utils


#20

Según esto: “Note that directories are checked recursively.”

¿Has probado metiendo solo la ruta de la carpeta sin asteriscos?