 Il faut présenter, keep it, something, a the table. Bonsoir. Derrière le jeu de mots, le but c'est vraiment essayer de vous présenter, faire un rappel ou une présentation, j'espère que ce sera plus un rappel pour la plupart, sinon tant mieux pour vous. Des annotations de type en piton à travers toutes les versions et surtout en quoi ça peut vous aider à régler le problème de la complexité de votre code en général. Et je vais commencer par un warning, un disclaimer. C'est que dès qu'on parle de type dans un langage dynamique, ça déclenche assez vite des guerres de religion, des débats enflammés. C'est important de se rappeler que c'est des annotations de type et pas des déclarations de type, donc ça reste que de métadonner qu'on ajoute dessus. Et si il y a des gens qui ne connaissaient pas, qui s'inquiètent, on va pas ajouter de type, on va pas forcer de type pour l'instant, on pourrait rester calme. Et ça a été confirmé dans plusieurs pêpes, à plusieurs occasions, donc il n'y a aucune inquiétude si ça vous inquiétez déjà. Donc on va essayer de prendre un peu de recul. Quel est notre objectif qu'on écrit du code ? Déjà le premier constat, a priori peu importe ce que vous faites. Dès que votre code est un petit peu volumineux, vous passez beaucoup plus de temps à lire votre code qu'à l'écrire. Dès que vous voulez faire n'importe quel backflick, ça joue de futur, vous interagissez avec beaucoup plus de codes existants, que ce soit vous qui l'avez écrit, il y a extents ou n'importe qui d'autre. Donc déjà, le but le plus important, c'est de faciliter la vie du lecteur du code plutôt que de la personne qui va l'écrire, puisque c'est là qu'il y aura le plus de dues à vie. Et que chaque action que vous faites sur votre code base, que ce soit ajouter ou supprimer quoi que ce soit, a un impact sur sa complexité. C'est jamais nul. Donc si vous ne l'améliorez pas, iterativement vous faites juste empirer la complexité de votre code. Et pourquoi cette complexité importante ? C'est qu'au plus le code est complexe, au plus vous avez du mal à repérer les bugs ou à les corriger, au plus ajouter des features va vous coûter cher, parce que vous allez avoir plus de choses à gérer. Et donc partant de cette complexité et du fait que vous passez plus de temps à lire le code qu'à l'écrire, il est assez primordial de masquer toute la complexité ou de la gérer à l'intérieur de vos implementations et faire que vos interfaces soient les plus clignes possible, il faut pas me croire sur parole, déjà c'est du bon sens, mais il y a un livre que je vous encourage beaucoup à lire parce qu'il n'est pas lu, Philosophère Software Design, qui l'explique en long en large et qui vous convaincre si vous n'y croyez pas. Et qui dit exactement la même chose, c'est d'il y a un élément de design de votre software qui est là, il y a forcément une complexité qui sera associée et n'importe quel développeur qui aura besoin d'interagir avec ce code, que ce soit le code que vous avez écrit la semaine dernière, que ce soit une libraire que vous utilisez ou qu'il y a un membre de votre équipe écrit, il sera obligé de connaître comment utiliser ce bout de code. Si l'interface n'est pas évidente, forcément la personne sera obligée d'aller lire le code et forcément il y aura plus de temps à passer dessus, beaucoup plus de risques de bugs, beaucoup plus de charges cognitives. Je crois que c'est ce qui résume le mieux. Il y a un peu plus vite, donc je parle beaucoup de complexité, c'est joli mais c'est très abstrait. Peu importe comment vous le mesurez, nous serions toujours auprès de 3 axes. Le premier c'est l'amplification du changement, c'est-à-dire quelle quantité de code vous êtes obligé de modifier pour réussir à implémenter le but de ce que vous voulez faire, que ce soit que vous avez un bug ou que vous ajoutez une feature. Au plus il y a de code à modifier, au plus c'est complexe, ça paraît évident mais ça reste un fait, la charge cognitive de votre code, combien d'informations vous êtes obligés d'avoir dans votre contexte pour appliquer votre tâche et enfin toutes les inconnues. Donc toutes les hypothèses que les développeurs vont faire qui seront vérifiées ou pas vérifiées mais qui pourront causer des bugs. Et ce qui est intéressant c'est que sur ces 3 axes principaux de définition de la complexité, il y en a 2 qui directement se retrouvent au niveau des interfaces en piton, enfin des interfaces dans quelques langages que ce soit qui sont la charge cognitive et les inconnues. Donc si on essaie de régumer ça avant d'entendre le vie du sujet, la complexité de votre code suivant les axes fait qu'au plus votre code est complexe vous vous risquez d'avoir des bugs, au plus vous allez être long à développer des features si vous en avez à faire, quand vous en avez à faire. Donc votre tâche en tant que développeur à n'importe quel moment où vous vous interagissez sur du code, comme dirait un club-up c'est de laisser le camp plus propre que quand vous y êtes arrivé, mais c'est vraiment de tout réduire la complexité sinon vous faîtes que l'augmenter. Donc le meilleur moyen pour ça c'est elle disparaît pas toute seule mais au moins faut la masquer parce qu'il n'y a que la personne a priori vous qui travaille sur l'implémentation qui gère cette complexité-là et les développeurs qui utiliseront votre implementation le but c'est de leur cacher ça le plus possible pour faire qu'il ait moins de bugs et que ça aille plus vite à développer après. Et sachant que la prochaine personne sera priori vous-même vous serez content d'avoir fait. On va rentrer dans les annotations pour voir comment on adresse cette complexité-là et ce qui est intéressant, je voulais commencer par là c'est l'historique parce qu'on a réglement la surprise quand on rencontre notre développeur c'est que les gens, enfin beaucoup de personnes pas tous heureusement pense que c'est une feature assez récente la première pep qui décrise les annotations de fonctions à plus de 12 ans. Donc c'est quand même quelque chose qui on a eu le temps de le lire quand même de la similar en principe et on voit que ça s'est quand même accéléré un peu plus loin donc on va repasser très rapidement sur ce que ça apporte le langage progressivement y compris en plus de 2.7 je pense que c'est un élément intéressant c'est que dès qu'on parle de features qui ne sont pas forcément utilisés par tout le monde et que les gens pensent que c'est des nouveautés on peut les utiliser en plus de 2.7 la façon la plus courante que les gens utilisent enfin la plus courante très courante en tout cas que les gens utilisent pour décorer les documentés pardon les types de vos fonctions de vos modules c'est simplement les commentaires on voit par exemple tous les commentaires tips faim c'est très pratique ça remplit déjà un bon besoin donc si vous le faites c'est déjà très bien mais il y a une relation avec le dash type qui permet d'aller beaucoup plus loin on verra les exemples mais l'intérêt c'est en plus de savoir que vous avez juste un dicte par exemple ça vous dira quelles sont les types de clés de valeur de votre dicte est-ce qu'il peut être nul ou pas et puis par contre en plus de 2.7 on peut l'utiliser mais ça serait trop beau si on avait toutes les features notamment le type of name tuppers il laisse un peu la désirée je vais passer très rapidement sur les exemples de syntaxe parce qu'on a beaucoup de talks ce soir attention je partagerai cela il y a près mais dans l'idée ça c'est ce que vous avez sur l'habitude de voir avec des notations de tips faim donc tout est en commentaire ce qui donne comme un bon outil un bon support de documentation quand on ajoute des annotations ça ressemble à ce genre de choses donc ça, l'intérêt de modifier c'est que déjà la structure des données est séparée de la sémantique en tant que développeur vous avez vous portez ça de manière différente et surtout les outils peuvent gérer ces annotations là on verra après et les outillages mais à partir du moment que c'est automatisable ça fait que vous avez des tests dessus d'équivalent de lintes j'espère que tout le monde dit des lintes ou fait des tests qui vont tester ces types ce qui vous facilitera beaucoup la tâche par derrière par contre, une des limites c'est que justement comme ça s'ajoute à la fin des lignes et que les lignes peuvent être assez grandes si vous avez beaucoup de paramètres ça peut donner ce genre de notation ce que je ne vous souhaite pas d'utiliser autant j'aime beaucoup les annotations de tips je pense que personne sera super à l'aise avec ce genre de notation qui n'est pas très agréable mais ça existe et ça peut être supporté donc c'est toujours un compromis tout dans la vie il faut faire des trade-offs et là où c'est intéressant c'est intéressant ce qui est intéressant à savoir c'est que les NEMTOPL en Python 2.7 j'ai jamais réussi il y a bien des documentaires en type donc si vous avez des NEMTOPL de ce genre là on est obligé de faire un fallback sur ce qui est habituel si quelqu'un connaît l'astuce pour JSON 2.7 j'aimerais lui parler après ou ne pu utiliser Python 2.7 ensuite on accélère un peu dans le temps je commence à Python 3.4 puisque les versions précédentes je ne pense pas qu'elles sont encore très utilisées je traite le 3.4 et 3.5 en même temps ce qui est intéressant c'est de voir quand j'ai défini ce qu'apporte la gestion de la complexité au niveau de votre code le focus principal est sur l'interface c'est-à-dire que c'est vraiment la façon dont la personne qui utilise votre composant, votre fonction, votre module peu importe va l'utiliser qui est la plus importante et ce qui est très intéressant à voir c'est que les premières annotations de type qui ont été ajoutées c'est justement sur les fonctions d'abord en 3.4 sur les retours des fonctions entre 3.5 sur les arguments donc je traite les deux en même temps pour aller plus vite c'est vraiment le même principe on reprend le même exemple donc ce qu'on voit c'est à la ligne 6 vous avez le retour où le tuppel est défini donc on sait exactement que là c'est un tuppel mais d'ailleurs avec des dictionnaires c'est encore plus pratique enfin plus pratique je trouve ça plus pratique parce qu'on a plus besoin d'édictionnaires dans notre use case mais vous savez exactement quelles sont les types qui sont inclus dans vos objets et pareil ce que Python 3.5 vous apporte ces annotations des arguments ou maintenant on trouve par exemple l'exemple des dictionnaires je l'ai fait pour avoir un peu de request donc le nid tua un peu le propos mais ça montre par contre que vous avez des notations de type mais que ça ne vous donne pas des types statiques, forts vous gardez la liberté du Python où les types peuvent être très variés qu'est-ce qu'on a dedans et par contre qu'on voit qu'on voit que l'intérieur de votre implementation il n'y a pas encore ce support des notations où on est obligé d'utiliser les commentaires comme en putain 2.7 donc ça c'était 3.4, 3.5 à partir de 3.6 les variables peuvent être à noter donc ce qu'on a vu juste avant on a vu juste avant que ce n'était pas encore supporté et surtout avec les mises à jour de MyPy dont parlera après le support de NEMTOPOL est devenu vraiment beaucoup plus intéressant beaucoup plus riche et donc le support des types là je ne mets que des alias parce que c'est en général la première façon que vous allez vouloir l'utiliser mais vous pouvez définir beaucoup plus que ça créez vous même entre guillemets vos propres types on reste d'accord c'est que des alias et vous pouvez définir vraiment de manière beaucoup plus explicite quelles sont vos types de retours en tant que développeur vous voyez une fonction comme ça elle est assez trivial donc l'abstraction est assez facile à appréhender mais recevoir un HPE response qui est typé en dessous de fields on voit tout de suite ce qu'on a comme donné alors qu'il faut aller lire les commentaires vous passez beaucoup plus de temps ce qui est très intéressant pour finir c'est une parenthèse ou je reviens je me mets plutôt en avant une contradiction par rapport au PEP que j'ai c'était avant je ne sais pas si beaucoup de monde a regardé les data classes en 3.7 si vous n'avez pas encore eu l'occasion de jouer avec 3.7 je vous en crois j'ai regardé c'est assez pratique dès que vous avez des value-objects à créer c'est vraiment un objet un concept très pratique qu'ils ont mis mais un détail intéressant c'est que dans ce que là en 3.7 les annotations types pour les data classes sont obligatoires c'est à ma connaissance ce l'exemple mais ça montre une direction qui vaut le coup d'être souligné je pense que c'est la seule fois pareil je me trompe peut-être mais la seule fois que les annotations types pour l'instant sont obligées en 3.7 donc c'est un exemple 3.7 plus complet que les data classes et on voit qu'on retourne directement à l'instance donc là on a vu comment les déclarer on a vu en quoi ça pouvait adresser en partie la complexité pourquoi ça va vous aider ce qui est très intéressant c'est que ça aide beaucoup le refactoring parce que les outils justement dès que tous vos tests vos linter vont vous aider tout de suite dès qu'il y a un ordinaire dans vos types la documentation aussi générer toute la documentation c'est beaucoup plus riche parce que vous avez des types qui sont plus documentés plus riches et pas d'expérience dès que vous refactorez dès que vous changez votre code je vous encourage vraiment à le tester vous verrez que ça fait une différence et ce qui si vous ne l'avez jamais testé c'est qu'au niveau de l'adoption comme c'est optionnel je sais pas si des gens ont joué avec TypeScript avant de côté frontaine ou back-end c'est des annotations que vous mettez où vous voulez et c'est entièrement optionnel vous n'êtes pas obligé de les mettre sur tous vos types vous les mettez juste là où vous les commencez donc vous pouvez très bien commencer avec une base de code existante n'importe le nombre de millions de lignes qu'elle aura vous en mettez une vous vérifiez que ça marche et que ça vous retourne une erreur et comme ça vous le mettez là où ça vous apporte quelque chose et vous pouvez les ignorer complètement ailleurs donc l'investissement initial est vraiment faible pour ça tout comme les gens ça n'a pas eu de lignes flakate peu importe chacun choisit ce qu'il préfère MyPy il y a la solution de référence il y a beaucoup d'autres outils mais si vous commencez avec les annotations de type c'est sûr que vous utilisez MyPy qui vous fera le même genre d'analyse sur vos types donc le genre d'erreur qui va être retourné c'est typiquement ce genre d'avertissement disant attention les valeurs que vous utilisez ne sont pas celles que vous avez déclarées donc ça vous a oublié de faire une mise à jour soit vous faites une erreur ce qui est quand même beaucoup plus rapide et surtout ces tests là ces erreurs là on n'a même pas besoin de tests d'écrire le moindre test pour recevoir l'erreur vous l'avez tout de suite ça n'empêche pas d'écrire des tests mais c'est vraiment très bon complément pour un coup qui est assez ridicule et un autre exemple que je n'ai pas mentionné mais qui est vraiment intéressant aussi c'est par exemple si vous laissez une twirling comme vous avez oublié donc vous retournez un tupper de les autres données de valeur là si vous n'avez pas un test unitaire ça va vous remarquer trop tard vous aurez directement d'alertissement en disant votre tupper c'est pas un tupper qui était attendu et vous aurez tout de suite votre erreur et finalement je reviens dessus c'est ces bénéfices là vous pouvez les avoir même députons 2.7 donc vous n'avez pas forcément comme je disais les NEM tupper tous les gains mais ça apporte déjà beaucoup beaucoup de valeur en plus de la partie test et automatisation il y a tous les outils que vous utilisez qui vont en profiter qui vont leverager donc là j'ai pris l'exemple avec PyCharm qui utilise ces annotations là pour directement vous donner plus d'informations donc on en revient à l'exemple ou le lecteur de votre code la personne qui a utilisé votre code a pas du tout besoin d'avoir l'implémentation pour avoir toutes les informations en tout cas le plus d'informations possibles pour utiliser l'abstraction que vous exposez avec votre méthode et c'est la même chose avec VS Code j'ai pris ces deux exemples parce qu'à priori ça couvre la plupart des codes d'utilisation mais ce qu'il faut revenir c'est que le support est vraiment bon dans à peu près tous les outils et comme je l'ai mentionné rapidement on peut créer soit même ses propres alias des titres d'exemple et on verra qu'on peut même aller plus loin pour créer des génériques on peut faire beaucoup beaucoup de choses on a vu ce que ça aide pour les factoring et pour les tests par contre on écrit quelque chose quel impact ça a sur notre code une fois qu'il tourne en production par définition enfin par défaut pardon il n'y a aucun impact en runtime donc il n'y a pas de risque de bug qui apparaissent en fait d'expérience c'est plutôt l'inverse et vous avez repéré les bugs en amont plus de bugs en amont et il n'y a aucun impact de performance parce qu'il n'y a absolument rien qu'il n'évalueait donc c'est pas une bonne excuse en plus on va pas mettre en cause notre production il n'y a aucun risque là-dessus donc il n'y a aucune excuse de pas le tester je vous encourage vraiment à le faire si on veut vraiment qu'on est un peu aventureux ou qu'on a envie de jouer on peut quand même utiliser des annotations de type en production de get typing INS qui en fait utilise un décorateur en dessous vous permet vous si vous faites de la réflexion par exemple d'aller chercher ces annotations pour les utiliser pour faire ce que vous aurez besoin de faire à l'occasion il y a d'autres flags comme le type checking qui permet le plus de mode CI de brancher votre code suivant que vous êtes en mode évaluation type ou pas et pour les trucs aventuriers il y a Package & Force qui vous permet là de forcer la vérification type runtime par contre c'est un impact en performance et selon moi si vous avez besoin d'aller jusque là pensez à notre langage aussi ça défaite un peu l'objectif mais ça existe c'est comme intéressant à regarder et comme je l'ai mentionné on peut faire des lgmox j'ai pas vérifié la version je crois que c'est depuis 3.5 on peut faire des overloads si vous voulez définir plusieurs fois la même fonction négative différent pour simplifier les signatures il y a quand même beaucoup de choses qui sont possibles et tout ça est supporté par pas mal d'outils donc mypy qui est vraiment l'incontonable si vous avez un seul à retenir c'est la porte d'entrée royale il y a plusieurs typesheds pareil qui vous permettent d'importer des annotations de type de package existant parce qu'à écrire les votres c'est pratique pour ce que vous rédigez utiliser des annotations de type pour des packages existants ça vous apporte beaucoup de documentation pour après ou aucun coup pas y est notre tête j'ai mentionné parce qu'il est assez intéressant j'ai eu un succès très mitigé quand j'ai testé il y a longtemps mais ça fait un... j'avoue que ça fait longtemps que j'ai pas testé ce qui est intéressant c'est qu'il vous génère des annotations de type sur une code base existante et la génèse intéressante aussi c'est que ça a été fait par Dropbox donc il y a une base de code assez consistante aussi et les torques de présentation de pas une tête ont été fait par Guido von Rasmund ça donne une certaine légitimité aussi au travail qui a été fait par derrière enfin c'est pas juste des gens motivés dans un coin il vous aurait volonté derrière de faire des choses intéressantes et si vous allez là-dedans il existe vraiment beaucoup beaucoup d'autres packages je vous encourage à y aller et puisque mypy il a pendant très principal si vous ne l'avez pas utilisé depuis longtemps je vous encourage à regarder les visageurs qui avaient été faites en même temps que 3.6 il me semble où il y a beaucoup d'options qui ont été rajoutées ça vous permet de le customiser exactement suivant vos besoins à quel point vous voulez stricte ou au contraire juste à faire des indices un peu comme pylinx qui a tendance à vous protéger beaucoup de customisation la vraie différence avec pylinx c'est que pylinx vous êtes obligé de le customiser sinon vous vous aurez son bruit et les defaults sont très utiles et par contre après vous l'adaptez à vos besoins on va essayer de voir PSAREP si on regarde le point de départ nos objectifs j'espère avoir au moins convaincu que les annotations types sont très complémentaires des commentaires et les enrichissent pour réussir à mieux documenter les abstractions et pour réussir à donner un meilleur tooling autour de ces abstractions franchement si vous les avez jamais testés c'est le moins d'y aller parce que ça vous permet d'automatiser tous ces tests-là et a priori ça vous permet de coder plus vite et passer moins de temps à juste lire du code existant et donc mal avec un peu de chance vous êtes convaincu vous avez envie de le tester donc les questions principales j'aurais pu faire un flowchart c'est comment est-ce que je pourrais l'utiliser, est-ce que je devrais l'utiliser comme j'ai montré bah même en plus ton 2.7 on peut l'utiliser on n'a pas tous les bénéfices on gagne déjà beaucoup le travail nécessaire pour commencer c'est celui que vous imposez qui a à part lié un peu de documentation au début vous pouvez commencer avec juste à noter une fonction dans une code base existante et ça il y aura qu'un peu avec le reste qui n'est pas noté les risques le seul c'est perdre du temps le tester puis voir que finalement ça vous apporte pas grand chose mais il n'y a aucun risque de casser le code existant et là je parle d'expérience et je suis biaisé mais franchement ça me permet de développer plus vite et en général de faire moins de bêtises tous les codes 18 les annotations sont comme trackers en avant et pour finir je reprends cette situation un des points les plus intéressants ce que j'aimerais réussir à vous convaincre c'est que que vous l'utilisez ou pas peu importe en fait chacun son problème ses ressources ses contraintes par contre ne pas l'utiliser ça doit être un choix on doit dire tiens cette feature là m'apporte pas grand chose je peux pas me permettre je veux pas utiliser quand on essaie de rencontrer des gens je voyais trop souvent des gens qui n'utilisaient pas simplement parce que ça n'avait pas existé pas assez ce que ça apportait donc au moins j'espère avoir attiser votre curiosité pour aller vous voir un peu plus vous renseignez un peu plus dessus histoire de pouvoir faire ce choix et pas juste ne pas l'utiliser parce que vous savez pas c'est à quoi ça sert ou vous étiez passé à côté parmi la la quantité de features qu'il y a donc c'est à peu près tout je partagerai les slides comme je l'ai mentionné il y a quelques ressources surtout les BEP sont très intéressantes parce qu'elles sont vraiment très complètes et j'espère ça vous a plu que j'ai pas été overtime donc si c'est le genre de débat qui vous intéresse discussion plus ou moins passionné on charge du monde merci beaucoup merci Maxime question oui ici on utilise des annotations de type finalement comme vous l'avez présenté est-ce que on va conserver aussi les les infos sur le type dans la docstring des fonctions ou ce que j'ai tendance à faire parce que toutes les recommandations de format docstring ont le type par défaut et je trouve que c'est un peu redondant est-ce qu'il y a des recommandations à ce niveau-là c'est une bonne question j'avoue que la plupart du temps le doc j'interesse pas d'interesser par les modèles je suis plus sûr à 100% il me semble que oui mais honnêtement je suis plus sûr à 100% c'est tellement pas d'autu ce qu'est-ce que... dans les exemples vous avez montré à plupart du temps quand vous utilisez les annotations de type vous avez enlevé le docstring les informations de type après il y a un truc qui empêche vu que le type est déjà défini il n'y a rien qui empêche de le mettre dedans c'est c'est plus verbe mais ça a rempli deux objectifs différents en fait il y a d'un côté la gestion de doc d'autre côté tous les tests à moins qu'il était sur la gestion de doc mais je ne peux vraiment te quitter de face qu'il a fait des types dans toutes les annotations dans les deux clans merci