La plus grosse erreur de stratégie dans la gouvernance de Python est bien l'asynchrone au point que même Django, Flask ou Peewee ont fini par céder alors que gevent est juste incroyable pour éviter le syndrome "De quelle couleur est ta fonction ?"
Cette fragmentation oblige à bien choisir ses librairies/frameworks et complique vraiment la donne.
Globalement, je n'utilise pas le typage statique et je ne peux donc pas me prononcer sur les problèmes invasifs que tu relèves avec mypy et ton article ne m'encourage pas à m'y mettre.
Quelques remarques ceci dit:
Avec ton exemple de httpx.get le souci est aussi et avant tout qu'on a affaire à un bon vieux "code smell" avec trop de paramètres
Ensuite:
Parfois, on se retrouve à faire des imports croisés uniquement pour l'annotation.
En quoi serait-ce différent si on ne les utilisait pas ? Globalement ton article manque un peu de d'exemples concrets et détaillé pour appuyer tes propos à mon sens.
Et enfin une petite typo:
Merci d'avoir lu*t* jusqu'ici
PS: Je ne comprends pas le moinssage: Pointer un article technique de son blog pour engager une discussion ne me parait pas contrtevenir l'esprit de la section "liens" et change des articles quelconques de journaux qu'on nous ressert en guise de passe plats .
PS: Je ne comprends pas le moinssage: Pointer un article technique de son blog pour engager une discussion ne me parait pas contrtevenir l'esprit de la section "liens" et change des articles quelconques de journaux qu'on nous ressert en guise de passe plats
Je soupçonne des fans qui ont réagit au titre en voyant « Contre … Python »
“It is seldom that liberty of any kind is lost all at once.” ― David Hume
Avec ton exemple de httpx.get le souci est aussi et avant tout qu'on a affaire à un bon vieux "code smell"
L'API httpx, comme celle de requests dont elle s'inspire, sont pourtant reconnu parmis les meilleures API Python. Loin devant urllib. Sa souplesse fait sa simplicité d'utilisation et sa complexité d'implémentation.
L'API httpx, comme celle de requests dont elle s'inspire, sont pourtant reconnu parmis les meilleures API Python.
Ca en dit long sur la mentalité et l'état d'esprit des devs Python …
Une fonction à 11 paramètres, c'est juste … euh … de la merde ?
Je reproche d'ailleurs à certaines réimplémentations de libs python ce côté "on va faire une fonction/méthode pour grouper ce qui était fait par 3 ou 4 fonctions/méthodes", la cntrepartie étant de faire augmenter inutilement le nombre de paramètres passés à cette fonction, rendant l'utilisation de celle-ci compliquée.
Personnellement je trouve que Python est de moins en moins cohérent. Au début j'avais été séduit par l'illusion que ce langage donnait (code propre, simple, etc). Mais j'ai de plus en plus de mal à coder en python au fur et à mesure de l'évolution du langage.
La on parle d'une commande qui est un point d'entrée unique, pas d'une fonction. D'autre part, une bonne pratique de développement est de passer une structure ou un objet lorsqu'une fonction prend plus de 3 ou 4 paramètres. Enfin, lorsque j'écrivais ça, je pensais surtout à des trucs style popen, popen3, etc … qui ont le mérite d'être relativement simple ( je dis bien relativement simple parce qu'en pratique quand on commence à les utiliser c'est pas si simple que ça).
Maintenant, si tu veu parler de commande … il y a pas mal d'outils qui splittent les commandes en 2 ou trois, voir plus ( je pense à podman par exemple).
Une fonction à 11 paramètres, c'est juste … euh … de la merde ?
En Python, les paramètres nommés changent quand même pas mal la donne par rapport aux langages où les paramètres sont seulement positionnels.
Sinon, je pense qu'avoir les types précis de chaque paramètre est bénéfique. Après, effectivement, il faut que la doc les présente de façon lisible. Peut-être avec l'indentation proposée par Étienne ou des points de suspensions pour les types longs, quitte à avoir le détail ailleurs. Ou à nommer les types et afficher ces noms plutôt que leurs expansions.
Les types, c'est comme n'importe quelle sous-expression, si ça devient complexe ou long on peut utiliser des variables permettant de leur donner des noms.
Ensuite, si un fichier manipule un type, il me semble cohérent que le type soit importé. Sinon ça y est, c'est le retour des fonctions dont le type des paramètres n'est pas clair. Je suis aussi plutôt contre remplacer les vérifications de types par des tests. Les deux méthodes de vérification sont complémentaires et les tests qui font le travail d'un vérificateur de type, c'est pénible.
Bref, je comprends les arguments de l'article, mais je pense que c'est améliorable sans se débarrasser des annotations de types (qui empire le résultat) et que sinon, c'est un mal pour un bien.
Cette mode du typage, elle a une bonne raison de se développer (et faire son retour), après des années de galères dans des langages typés implicitement / dynamiquement.
En Python, les paramètres nommés changent quand même pas mal la donne par rapport aux langages où les paramètres sont seulement positionnels.
Ce n'est pas seulement une question de repères nom/position. Il s'agit surtout du fait que si une fonction/méthode prend trop de paramètres, celà signifie bien souvent que cette fonction, ou l'objet associé a trop de responsabilités.
Cette problématique n'est pas propre à Python, mais à tout langage.
La délégation de responsabilité peut se faire via des objets plus petits qui auront leurs propres méthodes dans le cas d'un langage objet, ou via des structures qui auront des fonctions permettant de les manipuler (on a des tas d'exemples comme ça dans le noyau Linux, dans les noyaux BSD, avec les API permettant de manipuler les structures de noyau).
La comparaison (fonctions/méthodes/classes de codes sources -vs- arguments/options de commandes/programmes) n'est pas adéquate. Mais cependant, c'est bien ce qui se passe (ou devrait normalement se passer) dans le (écosystème du) libre : curl/wget/httpie/etc, devraient prendre en charge le TLS en s'appuyant sur libtls/libssl ; et au niveau des sources on ne devrait pas avoir d'interface avec onze entrées…
“It is seldom that liberty of any kind is lost all at once.” ― David Hume
C'est vrai. Cependant, ici, on parle d'une fonction dont l'objectif est de tout exposer. Ce serait compliqué dans un langage sans paramètres nommés.
Les choses sont à priori bien séparées par ailleurs.
(et donc oui, c'est comme curl qui expose toutes ses fonctionnalités avec des paramètres en ligne de commande. L'API C est par ailleurs probablement bien séparée)
Pointer un article technique de son blog pour engager
J'ai pas pensé à ça. Effectivement, le marqueur autopromotion est assez péjoratif. Tu as compris, je m'en cogne de faire ma promotion. D'ailleurs, c'est pas en écrivant un article tous les 3 mois que je vais monétiser mon audience XD.
On dirait que toutes les remarques touchent les outils et l'écosystème. La sortie de la fonction help qui devrait simplifier les annotations. Ou les afficher plus simplement. mypy qui devrait être plus inclusif. Mais je suis partial : j'ai utilisé les annotations de types, parce que c'est bien, mais jamais mypy, parce que mes projets n'ont jamais été aussi gros.
Mais se battre avec le typage, ça, j'ai donné avec Typescript. Et je dois dire que j'adore ça !
Le format de help devient certes très verbeux avec cet exemple, mais à y regarder de plus près, la fonction possède déjà 11 arguments, ça commence à faire et les types admis pour chacun sont multiples, donc oui c'est long, mais c'est peut-être aussi un signal pour réécrire/utiliser la fonction différemment, comme configurer le proxy ou les certificats à l'aide d'une session. (longue cette phrase n'est-ce pas ?)
Et l'affichage de help en cli n'aide pas forcément, avec un IDE et un typage affiché uniquement au survol, la surcharge visuelle serait bien moindre par exemple.
Le typage est aussi un bon moyen de faciliter la relecture du code par soi-même ou un nouveau venu en sachant quel est le type attendu des arguments. Et oui, mypy est parfois casse-pied mais personne n'est obligé de l'utiliser, ni de l'utiliser à 100%. Le typage est toujours facultatif et on pourrait voir des améliorations dans sa gestion plus tard.
Dans tous les cas, le typage n'est qu'un outil supplémentaire à notre disposition pour améliorer notre code, comme le sont les tests unitaires ou les tests fonctionnels. Pourquoi vouloir les opposer ?
Tu ne t'es jamais battu pour mettre en place une batterie de test ? Entre les tests qui cassent à cause d'une api externe down/timeout, le temps de run des tests, les pipelines de test cross-components… Il y a aussi de quoi devenir dingue avec des tests qui pourtant sont primordiaux pour assurer une qualité de produit/service ;)
c'est peut-être aussi un signal pour réécrire/utiliser la fonction différemment,
Tu propose vraiment de réécrire l'API de httpx.get pour simplifier les annotations ? C'est une API très pratique et très simple à l'usage.
Le typage est aussi un bon moyen de faciliter la relecture du code par soi-même ou un nouveau venu en sachant quel est le type attendu des arguments.
Je n'en suis pas convaincu du tout. À l'expérience, j'ai plutôt vu de l'accumulation de hack pour plaire à mypy. Ça devient un obstacle pour rentrer dans le code.
Pourquoi vouloir les opposer ?
Je compare les options que nous avons pour bâtir une stratégie de qualité du code. Chacun apporte sa garantie, son coût en terme de maintenance, de temps de CI (pytype est leeeennnnt), etc.
Tu ne t'es jamais battu pour mettre en place une batterie de test ?
Pas autant. Avec clean architecture, c'est même un plaisir. Autant mypy est pénible, autant pytest est du bonheur à utiliser.
Ça revient à planquer des imports dans les annotations. a.A dans l'exemple de la PEP. Je ne suis pas convaincu non plus du gain. ForwardRef est une rustine. Je veux bien connaître un langage qui fait ça, en dehors de Python.
Ça reste des annotations indicatives, que tu peux mettre ou pas, et que le langage ignore — c'est uniquement pour les outils qui veulent faire des contrôles.
Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141
Outre ce que tu écris très bien il manque peut-être ce qui est au fond l'argument le plus simple et le plus évident: le langage n'a pas été conçu dans cet esprit et même plutôt dans une direction “transversale.”
Il y a plein de mécanismes ou de traditions en Python, qui ne se combinent pas bien aux annotations de typage: les fonction qui travaillent directement sur leur argv ou kwargs, les fonctions polymorphes (souvent les constructeurs) qui permettent souvent d'avoir un code concis et expressif.
Si on veut tirer parti du typage statique autant utiliser un langage de programmation qui fait ça bien, comme OCaml par exemple, et qui a été pensé dès le départ pour cette discipline de type. Notamment avec l'inférence de types et une puissante algèbre de types.
Bien-sûr ne pas utiliser les annotations de type se paie quelque part, dans le “test coverage.”
Pour finir je pense que pour rendre ton article encore plus intéressant tu pourrais changer ton intro. Le “ça m'agace” à la rigueur ça n'intéresse que toi et tes collègues mais si tu exprimais un point de vue plus général, qui aiderait le lecteur à se faire une idée de si les annotations de type sont bien pour son projet au pas. Un truc du genre “L'introduction des annotations de type introduisent une nouvelle dimension pour décrire la pratique des équipes de programmeurs. Dans l'état actuel de cette technologie les bénéfices d'une adoption ne justifient pas dans notre contexte l'effort investi que nous préférons réserver à nos tests.”
Pour ma part j'ai fait du OCaml pendant de longues années et j'ai toujours beaucoup aimé la capacité du compilateur (ou de merlin) à détecter beaucoup d'erreurs très tôt dans le cycle de développement, surtout dans tout ce qui est les “cas limite.” Cette expressivité est notamment super agréable pour faire du multi-threading, avec en plus les monades permettent de “composer” les traitements asynchrones comme si c'était des fonctions habituelles.
Maintenant je fais surtout du Lisp, c'est un optimum complètement différent dans l'espace des langages de programmation… mais la discipline apportée par la longue pratique du typage statique est précieuse!
Tout à fait. Cet argument, plus pointu pour moi, est développé dans l'article d'Armine Ronacher, en 2014 Revenge of the types. J'essaie de garder les articles concis.
tu pourrais changer ton intro. Le “ça m'agace”
J'ai pas résisté à souffler dans l'appeau à troll :-)
Ton expérience en langage de programmation est vraiment intéressante. Ça me ferais plaisir de lire un journal de ta plume sur le sujet. On manque beaucoup de point de vue critique sur ce sujet, avec une vraie expérience et sans dogmatisme. Il y a une type-mania (revenge of the types comme dit Armine Ronacher) qui occulte le débat.
Enfin, le typage statique correspond à un état-d'esprit où la qualité est un principe formel, démontrable. Je pense que c'est faux et qu'il faut prendre garde à cet état d'esprit. Si c'était vrai, alors il n'y aurait pas de NullPointerException et autres bugs dans les langages compilés.
Aucun rapport. Les NPE viennent du fait que null est une valeur particulière autorisée en plus du type en question.
Certains languages sont désormais null safety justement pour éviter ce problème.
La différence c’est que le langage t’imposes de vérifier la forme de ton Optional avant de t’en servir, et que c’est une erreur à la compilation d’essayer d’additionner par exemple des Optional Int entre eux.
Le problème avec null, que ce soit dans les langages compilés ou non, c’est que ta valeur peut potentiellement l’être à n’importe quelle moment, et que si ça arrive à un moment où tu as le malheur de ne pas if value == null ton programme risque de planter à l’exécution.
Donc soit ça t’impose de constamment vérifier si ta valeur est null à chaque utilisation, pour toutes les valeurs, ce qui en pratique me semble difficile à tenir, en plus avec un (sûrement léger) coût à l’exécution, soit prier pour que ça ne t’arrive jamais, mais bon.
Par contre, quand le langage n’autorise pas null, et qu’en tant que développeur ou développeuse, tu indiques explicitement que cette valeur peut être Nothing ou Just <la valeur qui t’intéresse>, non seulement tu as le plaisir de savoir que ton langage ne peut pas planter pour cette raison, et en plus, tu notes explicitement les endroits où tu n’es pas sûr d’avoir un résultat, ce qui te permet de gérer les erreurs d’une manière plus élégante (même si à partir de là on peut parler de Result, mais bref…)
J'ai vu cet article, très intéressant d'ailleurs. En l'occurence, urllib tombe dans le cas concret où bytes et str risquent fort d'être mélangés.
Cependant, j'ai été déçu par les erreurs remontés (What we found and learned). Elles sont très minimes. Quelques exemples :
Mypy-friendly code is also human-friendly
Je ne suis pas d'accord, justement.
Explicit return None when a function can return other values
Sérieux ? Est-ce un bug ça ? return est trop implicite maintenant ?
Et pour les vraies erreurs trouvées par mypy:
Bad default parameter values
Une erreur vraiment minime dans le code. C'est tout. Tout ça pour ça. urllib3 est un bon exemple d'investissement très lourd pour un retour minime. Je ne nie pas la satisfaction de l'équipe. Je suis juste pas convaincu par cet exemple.
Les mainteneurs d’urllib3 sont pour
Depuis plusieurs années, il y a beaucoup de bruit autour du typage statique dans Python. Si j'écrit contre, c'est justement pour donner un autre son de cloche et parce que j'observe ce sujet depuis quelques années sans être convaincu. L'argument d'autorité ne marche pas pour moi.
J’y connais quasiment rien en Python et je ne pratique pas du tout.
Du côté de PHP, le typage statique est une bénédiction. Certes le code ressemble à un mélange entre Java et TypeScript avec des $ et des -> mais le gain au niveau de la qualité des développements est importante. Il y a deux outils principaux (PHPStan et Psalm) et beaucoup trouve que c’est la plus grosse évolution de l’écosystème depuis la gestion des dépendances avec Composer.
La présence de deux outils génère une saine compétition et leurs approches sont complémentaires.
J’ai une question, mypy est-il le seul outil d’analyse statique ?
Merci pour le retour sur PHP, j'avais relevé PHPStan.
Dans le monde Python il y a pytype de Google, pyright de Microsoft (écrit en TypeScript), pyre de Facebook. C'est un peu le festival :-)
Paradoxalement, je préfère pyright dont l'inférence est plus performante, et donc s'adapte mieux à l'annotation partielle. Vue que c'est pensée pour VSCode, c'est assez souple et performant.
J'étais tellement en manque de typage en tant que développeur Python, que je fais maintenant du Rust !
Blague à part, le typage optionnel de python et les outils d'analyse du code comme mypy ont changé ma vie de développeur professionnel.
Pour citer rapidement quelques bénéfices depuis que nous utilisons le typage :
Je ne me pose que très rarement la question de ce que contiennent les variables
Mes outils de développement me propose et corriges sans difficultés les attributs d'objets
Les nouveaux développeurs qui rentrent dans un projet existant le font avec plus de facilité (le code est moins obscur)
Les outils d'analyse voient des bugs avant que l'on ne les constate de manière indirecte pendant le fonctionnement
Et de plus, les développements que je dois faire "vite fait", comme des scripts jetables, ne requières pas que j'indique le type.
C'était un petit partage d'expérience, avant de n'être influencé par la lecture de l'article et des commentaires. Désormais, je vais tout lire, promis !
J'ai déjà rencontré le genre de problème que tu décris quand j'avais hacké Facebook Flow pour lui faire cracher un AST typé d'un fichier JS (un cuisant echec, au bout de 24h d'analyse d'Angular.js, il n'avait toujours pas fini) , et je m'étais rendu compte que le résultat était imbitable.
Je pense, mais je peux me tromper, que c'est dû au mariage de la carpe et du lapin. Je m'explique :
À la base Python est un langage non typé, et dans ces langages on a l'habitude de ne pas nommer les types, les classes, donc ça donne des
parce que justement, on a pas nommé ce truc et chaque chose qui le contient en lui définissant une classe, pour la bonne raison qu'à la base, on a pas besoin puisque le compilateur ne vérifie pas.
En Java ou d'autres langage où le compilateur vérifie on a pris l'habitude de créer des classes pour n'importe quoi, et du coup le compilateur nous répondrai
get(Url,Type1,Type2//...);
Donc quand on commence à faire de la vérification de type sur des types non nommés, ça devient illisible.
« Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker
# Petit retour
Posté par El Titi . Évalué à 8.
Globalement je suis de ton avis.
La plus grosse erreur de stratégie dans la gouvernance de Python est bien l'asynchrone au point que même Django, Flask ou Peewee ont fini par céder alors que gevent est juste incroyable pour éviter le syndrome "De quelle couleur est ta fonction ?"
Cette fragmentation oblige à bien choisir ses librairies/frameworks et complique vraiment la donne.
Globalement, je n'utilise pas le typage statique et je ne peux donc pas me prononcer sur les problèmes invasifs que tu relèves avec mypy et ton article ne m'encourage pas à m'y mettre.
Quelques remarques ceci dit:
Avec ton exemple de httpx.get le souci est aussi et avant tout qu'on a affaire à un bon vieux "code smell" avec trop de paramètres
Ensuite:
En quoi serait-ce différent si on ne les utilisait pas ? Globalement ton article manque un peu de d'exemples concrets et détaillé pour appuyer tes propos à mon sens.
Et enfin une petite typo:
PS: Je ne comprends pas le moinssage: Pointer un article technique de son blog pour engager une discussion ne me parait pas contrtevenir l'esprit de la section "liens" et change des articles quelconques de journaux qu'on nous ressert en guise de passe plats .
[^] # Re: Petit retour
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 3.
Je soupçonne des fans qui ont réagit au titre en voyant « Contre … Python »
“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: Petit retour
Posté par Eh_Dis_Mwan . Évalué à 1.
Quel moinssage ? il est à 26 ? C'est à la fin de la guerre qu'on compte les morts
[^] # Re: Petit retour
Posté par Étienne BERSAC (site web personnel) . Évalué à 2.
L'API httpx, comme celle de requests dont elle s'inspire, sont pourtant reconnu parmis les meilleures API Python. Loin devant urllib. Sa souplesse fait sa simplicité d'utilisation et sa complexité d'implémentation.
D'ailleurs le typage statique de la fonction max() est horrible.
Merci !
Barf, c'est un sujet à troll. Ça ne m'étonne pas. OSEF.
[^] # Re: Petit retour
Posté par totof2000 . Évalué à 5.
Ca en dit long sur la mentalité et l'état d'esprit des devs Python …
Une fonction à 11 paramètres, c'est juste … euh … de la merde ?
Je reproche d'ailleurs à certaines réimplémentations de libs python ce côté "on va faire une fonction/méthode pour grouper ce qui était fait par 3 ou 4 fonctions/méthodes", la cntrepartie étant de faire augmenter inutilement le nombre de paramètres passés à cette fonction, rendant l'utilisation de celle-ci compliquée.
Personnellement je trouve que Python est de moins en moins cohérent. Au début j'avais été séduit par l'illusion que ce langage donnait (code propre, simple, etc). Mais j'ai de plus en plus de mal à coder en python au fur et à mesure de l'évolution du langage.
[^] # Re: Petit retour
Posté par Étienne BERSAC (site web personnel) . Évalué à 3.
C'est une fonction portail qui encapsule l'API détaillée, publique elle aussi.
Trouves-tu que curl a trop d'options ?
Python sert aussi à faire des scripts et ces API sont parfaites pour rédiger des scripts lisibles.
Mais bon, c'est un autre sujet.
[^] # Re: Petit retour
Posté par totof2000 . Évalué à 3.
La on parle d'une commande qui est un point d'entrée unique, pas d'une fonction. D'autre part, une bonne pratique de développement est de passer une structure ou un objet lorsqu'une fonction prend plus de 3 ou 4 paramètres. Enfin, lorsque j'écrivais ça, je pensais surtout à des trucs style popen, popen3, etc … qui ont le mérite d'être relativement simple ( je dis bien relativement simple parce qu'en pratique quand on commence à les utiliser c'est pas si simple que ça).
Maintenant, si tu veu parler de commande … il y a pas mal d'outils qui splittent les commandes en 2 ou trois, voir plus ( je pense à podman par exemple).
[^] # Re: Petit retour
Posté par raphj . Évalué à 4.
En Python, les paramètres nommés changent quand même pas mal la donne par rapport aux langages où les paramètres sont seulement positionnels.
Sinon, je pense qu'avoir les types précis de chaque paramètre est bénéfique. Après, effectivement, il faut que la doc les présente de façon lisible. Peut-être avec l'indentation proposée par Étienne ou des points de suspensions pour les types longs, quitte à avoir le détail ailleurs. Ou à nommer les types et afficher ces noms plutôt que leurs expansions.
Les types, c'est comme n'importe quelle sous-expression, si ça devient complexe ou long on peut utiliser des variables permettant de leur donner des noms.
Ensuite, si un fichier manipule un type, il me semble cohérent que le type soit importé. Sinon ça y est, c'est le retour des fonctions dont le type des paramètres n'est pas clair. Je suis aussi plutôt contre remplacer les vérifications de types par des tests. Les deux méthodes de vérification sont complémentaires et les tests qui font le travail d'un vérificateur de type, c'est pénible.
Bref, je comprends les arguments de l'article, mais je pense que c'est améliorable sans se débarrasser des annotations de types (qui empire le résultat) et que sinon, c'est un mal pour un bien.
Cette mode du typage, elle a une bonne raison de se développer (et faire son retour), après des années de galères dans des langages typés implicitement / dynamiquement.
[^] # Re: Petit retour
Posté par totof2000 . Évalué à 3.
Ce n'est pas seulement une question de repères nom/position. Il s'agit surtout du fait que si une fonction/méthode prend trop de paramètres, celà signifie bien souvent que cette fonction, ou l'objet associé a trop de responsabilités.
Cette problématique n'est pas propre à Python, mais à tout langage.
La délégation de responsabilité peut se faire via des objets plus petits qui auront leurs propres méthodes dans le cas d'un langage objet, ou via des structures qui auront des fonctions permettant de les manipuler (on a des tas d'exemples comme ça dans le noyau Linux, dans les noyaux BSD, avec les API permettant de manipuler les structures de noyau).
[^] # Re: Petit retour
Posté par Étienne BERSAC (site web personnel) . Évalué à 0.
C'est comme si tu disais que curl ne devrait pas faire du TLS, mais qu'il faudrait utiliser socat pour ça.
[^] # Re: Petit retour
Posté par ff9097 . Évalué à 3.
curl est une fonction ?
[^] # Re: Petit retour
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 4.
La comparaison (fonctions/méthodes/classes de codes sources -vs- arguments/options de commandes/programmes) n'est pas adéquate. Mais cependant, c'est bien ce qui se passe (ou devrait normalement se passer) dans le (écosystème du) libre : curl/wget/httpie/etc, devraient prendre en charge le TLS en s'appuyant sur libtls/libssl ; et au niveau des sources on ne devrait pas avoir d'interface avec onze entrées…
“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: Petit retour
Posté par raphj . Évalué à 2.
C'est vrai. Cependant, ici, on parle d'une fonction dont l'objectif est de tout exposer. Ce serait compliqué dans un langage sans paramètres nommés.
Les choses sont à priori bien séparées par ailleurs.
(et donc oui, c'est comme curl qui expose toutes ses fonctionnalités avec des paramètres en ligne de commande. L'API C est par ailleurs probablement bien séparée)
[^] # Re: Petit retour
Posté par Étienne BERSAC (site web personnel) . Évalué à 1.
J'ai pas pensé à ça. Effectivement, le marqueur autopromotion est assez péjoratif. Tu as compris, je m'en cogne de faire ma promotion. D'ailleurs, c'est pas en écrivant un article tous les 3 mois que je vais monétiser mon audience XD.
[^] # Re: Petit retour
Posté par GG (site web personnel) . Évalué à 5.
En faire un journal?
Pourquoi bloquer la publicité et les traqueurs : https://greboca.com/Pourquoi-bloquer-la-publicite-et-les-traqueurs.html
# Problème de fond, ou d'outils ?
Posté par Glandos . Évalué à 4.
On dirait que toutes les remarques touchent les outils et l'écosystème. La sortie de la fonction
help
qui devrait simplifier les annotations. Ou les afficher plus simplement.mypy
qui devrait être plus inclusif. Mais je suis partial : j'ai utilisé les annotations de types, parce que c'est bien, mais jamais mypy, parce que mes projets n'ont jamais été aussi gros.Mais se battre avec le typage, ça, j'ai donné avec Typescript. Et je dois dire que j'adore ça !
Bon, il se trouve que c'est le fondement même du langage.
[^] # Re: Problème de fond, ou d'outils ?
Posté par Étienne BERSAC (site web personnel) . Évalué à 3.
Oui. D'ailleurs, le principe d'annoter ne me gêne pas, surtout le retour de fonction par exemple.
Espèce de typoshiste ! :-)
# Points supplémentaires
Posté par Julien.D . Évalué à 5.
Le format de help devient certes très verbeux avec cet exemple, mais à y regarder de plus près, la fonction possède déjà 11 arguments, ça commence à faire et les types admis pour chacun sont multiples, donc oui c'est long, mais c'est peut-être aussi un signal pour réécrire/utiliser la fonction différemment, comme configurer le proxy ou les certificats à l'aide d'une session. (longue cette phrase n'est-ce pas ?)
Et l'affichage de help en cli n'aide pas forcément, avec un IDE et un typage affiché uniquement au survol, la surcharge visuelle serait bien moindre par exemple.
Le typage est aussi un bon moyen de faciliter la relecture du code par soi-même ou un nouveau venu en sachant quel est le type attendu des arguments. Et oui, mypy est parfois casse-pied mais personne n'est obligé de l'utiliser, ni de l'utiliser à 100%. Le typage est toujours facultatif et on pourrait voir des améliorations dans sa gestion plus tard.
Dans tous les cas, le typage n'est qu'un outil supplémentaire à notre disposition pour améliorer notre code, comme le sont les tests unitaires ou les tests fonctionnels. Pourquoi vouloir les opposer ?
Tu ne t'es jamais battu pour mettre en place une batterie de test ? Entre les tests qui cassent à cause d'une api externe down/timeout, le temps de run des tests, les pipelines de test cross-components… Il y a aussi de quoi devenir dingue avec des tests qui pourtant sont primordiaux pour assurer une qualité de produit/service ;)
[^] # Re: Points supplémentaires
Posté par Étienne BERSAC (site web personnel) . Évalué à 2.
Tu propose vraiment de réécrire l'API de httpx.get pour simplifier les annotations ? C'est une API très pratique et très simple à l'usage.
Je n'en suis pas convaincu du tout. À l'expérience, j'ai plutôt vu de l'accumulation de hack pour plaire à mypy. Ça devient un obstacle pour rentrer dans le code.
Je compare les options que nous avons pour bâtir une stratégie de qualité du code. Chacun apporte sa garantie, son coût en terme de maintenance, de temps de CI (pytype est leeeennnnt), etc.
Pas autant. Avec clean architecture, c'est même un plaisir. Autant mypy est pénible, autant pytest est du bonheur à utiliser.
# Imports croisés ?
Posté par lolop (site web personnel) . Évalué à 5.
Normalement pas nécessaire : https://www.python.org/dev/peps/pep-0484/#forward-references
«When a type hint contains names that have not been defined yet, that definition may be expressed as a string literal, to be resolved later.»
Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141
[^] # Re: Imports croisés ?
Posté par Étienne BERSAC (site web personnel) . Évalué à 4.
Ça revient à planquer des imports dans les annotations.
a.A
dans l'exemple de la PEP. Je ne suis pas convaincu non plus du gain. ForwardRef est une rustine. Je veux bien connaître un langage qui fait ça, en dehors de Python.# C'est pas du typage statique
Posté par lolop (site web personnel) . Évalué à 4.
Ça reste des annotations indicatives, que tu peux mettre ou pas, et que le langage ignore — c'est uniquement pour les outils qui veulent faire des contrôles.
Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141
[^] # Re: C'est pas du typage statique
Posté par Étienne BERSAC (site web personnel) . Évalué à 2.
Certes, mais mypy contraint le typage. En terme d'exécution, ça n'est pas du typage statique. En terme de développement, si.
[^] # Re: C'est pas du typage statique
Posté par lolop (site web personnel) . Évalué à 5.
Mais tu n'es pas obligé d'utiliser mypy, tu peux continuer comme tu faisais avant.
Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141
[^] # Re: C'est pas du typage statique
Posté par Étienne BERSAC (site web personnel) . Évalué à 1.
Et au boulot ? Et dans les projets en général ? Pour ne pas utiliser mypy, je dois rester dans mon coin ?
# L'éléphant dans le magasin de porcelaine
Posté par Michaël (site web personnel) . Évalué à 8.
Outre ce que tu écris très bien il manque peut-être ce qui est au fond l'argument le plus simple et le plus évident: le langage n'a pas été conçu dans cet esprit et même plutôt dans une direction “transversale.”
Il y a plein de mécanismes ou de traditions en Python, qui ne se combinent pas bien aux annotations de typage: les fonction qui travaillent directement sur leur argv ou kwargs, les fonctions polymorphes (souvent les constructeurs) qui permettent souvent d'avoir un code concis et expressif.
Si on veut tirer parti du typage statique autant utiliser un langage de programmation qui fait ça bien, comme OCaml par exemple, et qui a été pensé dès le départ pour cette discipline de type. Notamment avec l'inférence de types et une puissante algèbre de types.
Bien-sûr ne pas utiliser les annotations de type se paie quelque part, dans le “test coverage.”
Pour finir je pense que pour rendre ton article encore plus intéressant tu pourrais changer ton intro. Le “ça m'agace” à la rigueur ça n'intéresse que toi et tes collègues mais si tu exprimais un point de vue plus général, qui aiderait le lecteur à se faire une idée de si les annotations de type sont bien pour son projet au pas. Un truc du genre “L'introduction des annotations de type introduisent une nouvelle dimension pour décrire la pratique des équipes de programmeurs. Dans l'état actuel de cette technologie les bénéfices d'une adoption ne justifient pas dans notre contexte l'effort investi que nous préférons réserver à nos tests.”
Pour ma part j'ai fait du OCaml pendant de longues années et j'ai toujours beaucoup aimé la capacité du compilateur (ou de merlin) à détecter beaucoup d'erreurs très tôt dans le cycle de développement, surtout dans tout ce qui est les “cas limite.” Cette expressivité est notamment super agréable pour faire du multi-threading, avec en plus les monades permettent de “composer” les traitements asynchrones comme si c'était des fonctions habituelles.
Maintenant je fais surtout du Lisp, c'est un optimum complètement différent dans l'espace des langages de programmation… mais la discipline apportée par la longue pratique du typage statique est précieuse!
[^] # Re: L'éléphant dans le magasin de porcelaine
Posté par Étienne BERSAC (site web personnel) . Évalué à 3.
Salut Michaël,
Merci pour ton commentaire très pertinent :-)
Tout à fait. Cet argument, plus pointu pour moi, est développé dans l'article d'Armine Ronacher, en 2014 Revenge of the types. J'essaie de garder les articles concis.
J'ai pas résisté à souffler dans l'appeau à troll :-)
Ton expérience en langage de programmation est vraiment intéressante. Ça me ferais plaisir de lire un journal de ta plume sur le sujet. On manque beaucoup de point de vue critique sur ce sujet, avec une vraie expérience et sans dogmatisme. Il y a une type-mania (revenge of the types comme dit Armine Ronacher) qui occulte le débat.
[^] # Re: L'éléphant dans le magasin de porcelaine
Posté par LeBouquetin (site web personnel, Mastodon) . Évalué à 5.
kwargs
pour moi c'est l'illustration même de la complexité de maintenance de code python. C'est l'exemple type qui m'a fait aimer le typage python :)[^] # Re: L'éléphant dans le magasin de porcelaine
Posté par ff9097 . Évalué à 2.
Je déteste également
kwargs
. Du coup impossible de savoir au niveau de la signature les paramètres possibles…# typage statique et NPE
Posté par ff9097 . Évalué à 6.
Aucun rapport. Les NPE viennent du fait que null est une valeur particulière autorisée en plus du type en question.
Certains languages sont désormais null safety justement pour éviter ce problème.
[^] # Re: typage statique et NPE
Posté par Étienne BERSAC (site web personnel) . Évalué à 3. Dernière modification le 20/12/21 à 21:16.
Hmm, dans mypy, on a
Optionnal
pour autoriser une valeurs àNone
. Idem avec le?
de typescript. Quelle est la différence ?[^] # Re: typage statique et NPE
Posté par ff9097 . Évalué à 2.
Python n'est pas un langage compilé, rien ne t'oblige à prendre en compte les alertes de types
[^] # Re: typage statique et NPE
Posté par Leirda . Évalué à 4.
La différence c’est que le langage t’imposes de vérifier la forme de ton
Optional
avant de t’en servir, et que c’est une erreur à la compilation d’essayer d’additionner par exemple desOptional Int
entre eux.Le problème avec
null
, que ce soit dans les langages compilés ou non, c’est que ta valeur peut potentiellement l’être à n’importe quelle moment, et que si ça arrive à un moment où tu as le malheur de ne pasif value == null
ton programme risque de planter à l’exécution.Donc soit ça t’impose de constamment vérifier si ta valeur est
null
à chaque utilisation, pour toutes les valeurs, ce qui en pratique me semble difficile à tenir, en plus avec un (sûrement léger) coût à l’exécution, soit prier pour que ça ne t’arrive jamais, mais bon.Par contre, quand le langage n’autorise pas
null
, et qu’en tant que développeur ou développeuse, tu indiques explicitement que cette valeur peut êtreNothing
ouJust <la valeur qui t’intéresse>
, non seulement tu as le plaisir de savoir que ton langage ne peut pas planter pour cette raison, et en plus, tu notes explicitement les endroits où tu n’es pas sûr d’avoir un résultat, ce qui te permet de gérer les erreurs d’une manière plus élégante (même si à partir de là on peut parler deResult
, mais bref…)# Les mainteneurs d’urllib3 sont pour
Posté par Nonolapéro . Évalué à 4.
https://sethmlarson.dev/blog/2021-10-18/tests-arent-enough-case-study-after-adding-types-to-urllib3
[^] # Re: Les mainteneurs d’urllib3 sont pour
Posté par Étienne BERSAC (site web personnel) . Évalué à 5.
J'ai vu cet article, très intéressant d'ailleurs. En l'occurence, urllib tombe dans le cas concret où bytes et str risquent fort d'être mélangés.
Cependant, j'ai été déçu par les erreurs remontés (What we found and learned). Elles sont très minimes. Quelques exemples :
Je ne suis pas d'accord, justement.
Sérieux ? Est-ce un bug ça ?
return
est trop implicite maintenant ?Et pour les vraies erreurs trouvées par mypy:
Une erreur vraiment minime dans le code. C'est tout. Tout ça pour ça. urllib3 est un bon exemple d'investissement très lourd pour un retour minime. Je ne nie pas la satisfaction de l'équipe. Je suis juste pas convaincu par cet exemple.
Depuis plusieurs années, il y a beaucoup de bruit autour du typage statique dans Python. Si j'écrit contre, c'est justement pour donner un autre son de cloche et parce que j'observe ce sujet depuis quelques années sans être convaincu. L'argument d'autorité ne marche pas pour moi.
[^] # Re: Les mainteneurs d’urllib3 sont pour
Posté par Nonolapéro . Évalué à 5.
J’y connais quasiment rien en Python et je ne pratique pas du tout.
Du côté de PHP, le typage statique est une bénédiction. Certes le code ressemble à un mélange entre Java et TypeScript avec des $ et des -> mais le gain au niveau de la qualité des développements est importante. Il y a deux outils principaux (PHPStan et Psalm) et beaucoup trouve que c’est la plus grosse évolution de l’écosystème depuis la gestion des dépendances avec Composer.
La présence de deux outils génère une saine compétition et leurs approches sont complémentaires.
J’ai une question, mypy est-il le seul outil d’analyse statique ?
[^] # Re: Les mainteneurs d’urllib3 sont pour
Posté par Étienne BERSAC (site web personnel) . Évalué à 3.
Merci pour le retour sur PHP, j'avais relevé PHPStan.
Dans le monde Python il y a pytype de Google, pyright de Microsoft (écrit en TypeScript), pyre de Facebook. C'est un peu le festival :-)
Paradoxalement, je préfère pyright dont l'inférence est plus performante, et donc s'adapte mieux à l'annotation partielle. Vue que c'est pensée pour VSCode, c'est assez souple et performant.
# Je suis en manque de typage
Posté par bux (site web personnel, Mastodon) . Évalué à 7.
J'étais tellement en manque de typage en tant que développeur Python, que je fais maintenant du Rust !
Blague à part, le typage optionnel de python et les outils d'analyse du code comme mypy ont changé ma vie de développeur professionnel.
Pour citer rapidement quelques bénéfices depuis que nous utilisons le typage :
Et de plus, les développements que je dois faire "vite fait", comme des scripts jetables, ne requières pas que j'indique le type.
C'était un petit partage d'expérience, avant de n'être influencé par la lecture de l'article et des commentaires. Désormais, je vais tout lire, promis !
🦀🐍 http://github.com/buxx 🖥 https://algoo.fr 📋 https://tracim.fr
[^] # Re: Je suis en manque de typage
Posté par LeBouquetin (site web personnel, Mastodon) . Évalué à 5.
🥰
(disclaimer : on bosse ensemble:)
# Récidive ou grands esprits ?
Posté par El Titi . Évalué à 4.
Etienne, c'est toi qui a commis ça ?
[^] # Re: Récidive ou grands esprits ?
Posté par Étienne BERSAC (site web personnel) . Évalué à 2.
Non ! Merci pour le partage !
[^] # Re: Récidive ou grands esprits ?
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 3.
On y voit clairement deux camps…
“It is seldom that liberty of any kind is lost all at once.” ― David Hume
# Nommage de type
Posté par Ontologia (site web personnel) . Évalué à 4.
J'ai déjà rencontré le genre de problème que tu décris quand j'avais hacké Facebook Flow pour lui faire cracher un AST typé d'un fichier JS (un cuisant echec, au bout de 24h d'analyse d'Angular.js, il n'avait toujours pas fini) , et je m'étais rendu compte que le résultat était imbitable.
Je pense, mais je peux me tromper, que c'est dû au mariage de la carpe et du lapin. Je m'explique :
À la base Python est un langage non typé, et dans ces langages on a l'habitude de ne pas nommer les types, les classes, donc ça donne des
parce que justement, on a pas nommé ce truc et chaque chose qui le contient en lui définissant une classe, pour la bonne raison qu'à la base, on a pas besoin puisque le compilateur ne vérifie pas.
En Java ou d'autres langage où le compilateur vérifie on a pris l'habitude de créer des classes pour n'importe quoi, et du coup le compilateur nous répondrai
Donc quand on commence à faire de la vérification de type sur des types non nommés, ça devient illisible.
« Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.