Voici tout simplement comment je m’y suis pris pour intégrer mypy dans quelques projets. Ce billet suppose que vous utilisez git et que vous avez un système de tests en place.
Première Étape: Échafaudage
Cette étape consiste d’abord à installer mypy dans le projet et à le configurer. Ensuite, exécutez-le en comptabilisant le nombre de lignes et en les enregistrant dans un fichier. Par exemple:
mypy src | wc -l > mypy_err_count.txt
Techniquement ceci compte plus que le nombre d'erreurs, mais pour ce que nous voulons en faire c'est équivalent.
Ensuite ajoutez une étape à vos tests pour vous assurer que le nouveau compte d’erreurs n’est pas supérieur à ce qu’il était. Par exemple, en bash:
[ $(mypy src | wc -l) -lte $(cat mypy_err_count.txt) ]
Voilà, maintenant le compte d’erreur ne peut aller que dans une seule direction: vers le zéro.
Deuxième Étape: Itérations systématiques
C’est ici qu’on commence à ajouter les types partout. L’idée est d’utiliser l’étape précédente pour le faire de manière continue. C’est-à-dire que chaque jour on y met du temps puis on ouvre une requête de fusion au tronc commun. À chaque fois on doit prendre soin de mettre à jour le fichier mypy_err_count.txt
puis on ouvre une requête. Les autres contributeurs n’auront d’autre choix que de maintenir le statusd quo ou d’améliorer la situation, sans que le compte d’erreur augmenterait et les tests échoueraient. Évidemment vous devez refuser les demandes de fusion au tronc qui font augmenter le nombre d’erreur. Tout le monde doit contribuer.
Durant cette étape, il y a trois outils importants.
reveal_type
: Fonction qui imprime le type que mypy infère. C’est pratique lorsque les types deviennent complexe et que vous n’êtes plus certains de suivre. Ça peut aussi vous aider à déterminer si un type est incorrect à cause d’une erreur de votre part ou une erreur de mypy.#type: ignore
: Marqueur à placer à la fin d’une ligne pour ignorer les erreurs détectées sur celle-ci. Évidemment, vous devriez viser à l’utiliser le moins possible. Cependant, mypy n’est pas encore parfait et commet parfois des erreurs. Lorsque c’est le cas, c’est le bon moment d’utiliser#type: ignore
. La beauté: Avec les mises à jours de mypy, si un#type: ignore
devient inutile car la nouvelle version infère maintenant le bon type, vous aurez une nouvelle erreur qui vous indiquera que le#type: ignore
est inutile et peut être enlevé.cast
: Parfois il est logiquement impossible pour mypy de détecter le bon type. Un exemple classique:json.load
. Quel est le type qui en sort? Dict? List? Une liste de quoi? Si vous le savez, c’est le moment d’utiliser cast.
Troisième Étape: Retrait de l’échafaudage
Vous avez atteint zéro erreur? Bravo! C’est maintenant l’étape la plus facile. On retire le fichier mypy_err_count.txt
et on remplace le test basé sur celui-ci par une exécution directe de mypy.
Typer ou non les tests?
Bonne question. L’idée derrière mypy est de typer le code pour faciliter la découverte de bugs. Typer les tests vous aidera donc principalement à trouver des bugs… dans vos tests. Mais comme ce sont des tests, alors il planteront pendant que vous testez. Un peu circulaire non?
Bien que typer les tests puisse être utile, il vaut mieux se concentrer d’abord sur l’application comme tel. Ça adonne bien, mypy peut valider des répertoires ou non, donc si vos tests sont dans un répertoire (par exemple test), il suffit de l’exclure de la validation de mypy.
Ensuite, à vous de voir. Je pense que ça mérite d’être essayé sur quelques tests. Décidez ensuite basé sur cet essai si ça vaut la peine de poursuivre ou non.