Demat'iNal
Il m'arrive de soumettre des patch à des projets Python utilisant cette délicate innovation qu'est le système de typage pour Python. Si si, tu sais ces trucs à base de mypy qui cherchent à améliorer le monde en le rendant plus rigide.
Regardez donc cette beauté :
try:
from yaml import CSafeLoader as SafeLoader
except ImportError:
from yaml import SafeLoader
qui essaie d'utiliser la version native (et plus rapide) qui peut ne pas être présent sur le système, d'où l'alternative. C'est je pense assez idiomatique comme code.
Pour plaire au système de type, je vous propose ce code qui a de vieux relents de C
import typing
from yaml import SafeLoader as _SafeLoader
try:
from yaml import CSafeLoader
SafeLoader = typing.cast(type[_SafeLoader], CSafeLoader)
except ImportError:
SafeLoader = _SafeLoader
Y aurait-il une meilleur approche ?
# type: ignore
Posté par Frédéric Perrin (site web personnel) . Évalué à 10.
Je mettrais simplement un commentaire avec
type: ignore
:Personnellement, les types me sont très utiles. Ils attrapent beaucoup d'erreurs qui ne se signaleraient que bien plus tard. L'effort pour ajouter des annotations, et la difficulté pour annoter certaines constructions, vaut le coût.
[^] # Re: type: ignore
Posté par serge_sans_paille (site web personnel) . Évalué à 1.
Tiens tiens, une connaissance, salut, ça fait plaisir :-)
C'est la solution que j'ai utilisée au final, mais ce n'est pas très satisfaisant intellectuellement. C'est du typage graduel quoi Gradual_typing.
[^] # Re: type: ignore
Posté par Frédéric Perrin (site web personnel) . Évalué à 5.
Salut Serge ! J'avais pas vu le nom avant de répondre :)
Il m'est venu une autre idée :
Pas de
cast
ou detype: ignore
, et mypy peut vérifier que les opérations que tu fais surSafeLoader
sont valides à la fois avecCSafeLoader
etPySafeLoader
.Clairement c'est pas évident, c'est un exemple où le typage est plus difficile qu'il ne devrait l'être. Mais on pourrait aussi dire : pourquoi donc
yaml
ne détecte pas tout seul siCSafeLoader
est disponible, et force l'utilisateur à faire ces acrobaties :)Aussi, la syntaxe
blah: typ1 | typ2
est relativement nouvelle (Python 3.10 je crois?), utilisetyping.Union[typ1, type2]
si tu as un Python plus vieux.[^] # Re: type: ignore
Posté par flagos . Évalué à 2.
Ou pourrait implementer une classe abstraite qui servirait au typing.
# Double import
Posté par Glandos . Évalué à 2.
Je comprends le besoin, mais du coup, c'est pas un peu dommage d'importer la bibliothèque inutilement ?
J'avoue que parfois, j'ai trop d'obsession pour la performance…
[^] # Re: Double import
Posté par serge_sans_paille (site web personnel) . Évalué à 6.
J'ai mesuré, on est de l'ordre de 10-6 secondes pour l'import de
typing
# Mauvais compromis
Posté par ff9097 . Évalué à 10.
Je trouve que ce système de typage Python est un assez mauvais compromis au final. Ça ruine la clarté de python car c'est très verbeux et ça n'arrive pas a la cheville d'un vrai typage statique
[^] # Re: Mauvais compromis
Posté par steph1978 . Évalué à 0.
Question de goût probablement
[^] # Re: Mauvais compromis
Posté par cg . Évalué à 10.
Je suis d'accord. Python perd chaque année de sa simplicité et de sa beauté. Ça va finir par ressembler à du Rust (bim deux d'un coup :D).
[^] # Re: Mauvais compromis
Posté par David Delassus (site web personnel) . Évalué à 5. Dernière modification le 22 mars 2024 à 10:51.
Complètement d'accord.
Plus je l'utilise, plus je suis contre.
Il faut noter que
mypy
est un très mauvais outil, il abandonne très vite lorsqu'il s'agit d'inférer des types complexes. Pyright (qui est développé en typescript et inclus de base avec VS Code) est mieux, mais on a toujours pas un type-checker qui soit solide.Le système de type que Python propose est de plus peu expressif et ne fonctionne tout simplement pas dans des cas pourtant simple, par exemple :
Dans cet exemple,
mypy
ne sait pas inférer le type depayload_a
oupayload_b
.Et il sera impossible d'exprimer un type
Response
dont les variants dépendent du variant deRequest
:Comment exprimer que quand j'ai une
PayloadA
je reçois uneResponseA
? En Python c'est pas possible.De plus, Python est un langage qui est de nature purement dynamique. Aucun type-checker ne pourra vérifier la magie noire que l'on peut faire avec de la magie noire à base de subclasshook. Et pourtant ce sont des choses bien utiles parfois lorsqu'il est question de génération de code au runtime.
Au final, je deviens de l'avis suivant :
Si tu veux un système de type, tu veux un autre langage, alors utilise un autre langage.
https://link-society.com - https://kubirds.com - https://github.com/link-society/flowg
[^] # Re: Mauvais compromis
Posté par Frédéric Perrin (site web personnel) . Évalué à 5.
Dans mon expérience, 90% du typage c'est annoter les arguments des fonctions ou les attributs de classe avec
var: TypeDeVar
. Je manque peut-être d'imagination :) mais je ne sais pas comment on pourrait faire plus court. Peut-être plus d'inférences : Pourquoi est-ce que je suis obligé d'ajouter-> None
à toutes les routines qui ne renvoient rien du tout ? Sûrement quand j'ai un keyword argumentf(var=1)
mypy pourrait décider quevar
doit être de typeint
? Pour éviter ça je me suis senti obligé de mettre l'optionno-untyped-def
, qui est vraiment pédante.C'est vrai. C'est clairement un rajout qui s'intègre moyennement bien au langage (ex: le problème de Serge). Mon problème à moi serait plutôt combien il est facile d'avoir des
Any
un peu partout dès qu'on oublie quelque chose (ex : juste au-dessus), ou lorsqu'on utilise une bibliothèque tierce qui n'a pas de types.Dans l'ensemble et malgré tout ça, je trouve que c'est très utile, et ça m'évite un grand nombre d'erreurs avant de lancer mon code, donc j'utilise.
# La seule bonne méthode
Posté par David Delassus (site web personnel) . Évalué à 5.
Le
if typing.TYPE_CHECKING
n'est entré que lors du (roulement de tambours) type-checking par mypy.C'est aussi utile pour les imports circulaires (quand on a des classes définies dans plusieurs modules qui se référencent mutuellement via les annotations).
https://link-society.com - https://kubirds.com - https://github.com/link-society/flowg
[^] # Re: La seule bonne méthode
Posté par Ryzz . Évalué à 3.
Oui pour
typing.TYPE_CHECKING
, mais plutôt comme ça:[^] # Re: La seule bonne méthode
Posté par Colin Pitrat (site web personnel) . Évalué à 3.
Personnellement je préfère la méthode de Frédéric Perrin plus haut:
Ça dit vrament ce qui se passe en réalité , l'objet est soit d'un type soit de l'autre.SafeLoader: type["PySafeLoader"] | type["CSafeLoader"]
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.