Accueil / Blog / Métier / 2016 / Retour sur la PyConFr 2016

Retour sur la PyConFr 2016

Par Alex Marandon publié 18/10/2016, édité le 20/10/2016
Contributeurs : Gaël Utard, Sébastien Corbin, Simon Prévidente, Sylvain Boureliou
Nous étions présents à Rennes pour PyConFr 2016. Voici notre compte-rendu à chaud.
Retour sur la PyConFr 2016

Logo de PyConFr 2016

L'événement autour du langage Python qui se déroule chaque année en France sous la houlette de l'AFPY vient de s'achever. Cette année c'est Telecom Bretagne, école d'ingénieurs et centre de recherche situé à Rennes, qui accueillait l'événement. À en juger par l'affluence dans les salles, cette édition 2016 a été un grand succès.

Nous étions cinq développeurs de Makina Corpus à nous rendre à Rennes pour l'occasion et nous allons tenter de résumer ici ce que nous en retenons. Les conférences étaient organisées autour de grandes thématiques que nous allons reprendre ici.

La tendance est à l'asynchrone

Ludovic Gasc nous a fait une présentation très didactique de l'asynchrone en faisant un parallèle avec les baraques à frites. Vous l'aurez deviné, il est belge. Dans une baraque à frite synchrone, le serveur prend la commande, puis il cuit les frites, les emballes, prend la monnaie et sert le client. Ensuite, et seulement ensuite, il prend la commande du client suivant. Alors que dans une baraque à frite asynchrone, les commandes sont prises immédiatement, le serveur donne tout de suite sa boisson au client (car c'est très rapide à faire), puis le client sera notifié à l'aide d'un buzzer quand sa commande est prête (il n'a pas à demander toutes les deux minutes si ses frites sont prêtes).

Que retenir de sa présentation ?

  1. Asynchrone ne veut pas dire parallèle. Un code asynchrone tourne sur un seul CPU. Alors qu'un code parallèle tourne sur plusieurs CPUs. Mais rien n'empêche de mélanger le tout pour faire de l'asynchrone en parallèle.
  2. Asynchrone = coopératif : si une fonction dure trop longtemps ou bloque sans passer la main, elle empêche les autres coroutines de s'exécuter, contrairement aux threads qui sont préemptés par le noyau.
  3. Synchrone et asynchrone ne s'opposent pas. Il faut utiliser les deux en même temps.
  4. Parfois les threads ça peut aussi rendre service.
  5. L'asynchrone est à privilégier dans les cas suivants : la latence CPU est inférieure à la latence réseau (ce qui notamment le cas pour les réseaux mobiles), l'utilisation de protocoles stateful tels que les websockets (peu de données par rapport au temps de connexions), lorsque l'on a la possibilité d'utiliser le protocole HTTP2 (multiplexing, server push, ...) et dans le développement d'applications lourdes (GUI).
  6. C'était un bonne idée de rajouter le sucre syntaxique async et await directement dans la syntaxe du langage car plus simple à comprendre que la syntaxe @coroutine et yield from
  7. L'écosystème asyncio est très jeune (2/3 ans) mais offre déjà de nombreux modules : aiohttp (client/serveur HTTP), aiopg (PostgreSQL), aiomysql (MySQL), aioredis (Redis), AsyncSSH (protocol SSHv2), irc3 (client IRC), aiodns (résolution DNS), aiosmtpd (SMTP), et bien plus

Martin Richard a par ailleurs présenté le module asynctest qui étend les fonctionnalités du module standard unitest de Python pour permettre de tester plus simplement du code écrit avec asyncio (mocking d'une coroutine avec asynctest.mock.Mock et le context manager asynctest.mock.patch, simulation d'une boucle d'événements, ...).

Le cœur du langage à l'honneur

Cette édition de PyConFr a proposé de nombreuses conférences portant sur le langage lui-même et son fonctionnement interne. Serge « sans paille » Guelton a ouvert le ban avec une conférence pleine d'humour et très instructive où il a présenté son projet GAST, ce qui signifie fichtre en Breton. GAST fournit un arbre syntaxique commun aux différentes versions de Python et des utilitaires de conversion entre cette représentation générique et les différentes version d'AST. GAST est notamment utilisé par Pythran et peut servir à faciliter de développement d'outils d'analyse statique de code. Au passage Serge nous a initié au module standard ast et au parcours d'arbre syntaxique à l'aide du pattern visitor.

Ludovic Vaugeois a ensuite enchaîné sur les nouvelles f-strings, apparues dans Python 3.6, qui permettent de formater des chaînes à partir de variables du contexte courant avec une syntaxe de la forme f"lorem {expression} ipsum". Ce nouveau moyen de formater les chaînes viens s'ajouter au vénérable %, à la méthode format et à string.Template. Il offre des performances très intéressantes, avec des gains allant jusqu'à 200% par rapport à ce qui existait, au prix d'un inconvénient majeur : elles sont incompatibles avec l'i18n basée sur gettext.

James nous a fait patienter jusqu'à l'arrivée de Stéphane Wirtel en nous présentant Memopol, une plateforme de traçage des décisions politiques qui permet de noter les parlementaires en fonction de critères militants.

L'attente en valait la peine puisque Stéphane Wirtel nous a offert une présentation qui a probablement constitué pour beaucoup d'entre nous le clou de cette PyConFr. En effet Stéphane, contributeur à CPython qui nous vient de Belgique, nous a offert une visite guidée de CPython passionnante sur le plan technique et nous a montré la voie à suivre pour contribuer à notre tour. En suivant le voyage de l'expression x = 2 + 2 à travers les différentes strates de CPython, on a pu faire connaissance avec le lexer, l'arbre syntaxique, la compilation en bytecode, l'optimisation grâce au peepholer et l'exécution du bytecode par la machine virtuelle basée sur une pile. Stéphane a amusé l'assistance avec un exemple de modification de CPython qui permet de traduire les mot clés Python en français (à ne pas prendre au premier degré !) mais il a surtout insisté sur le fait que tout un chacun peut contribuer à son niveau à CPython, par exemple avec de la documentation, du tri de rapport de bugs et de la relecture de patch et pas seulement avec de l'écriture de code C ou Python.

Pierre-Yves David, développeur Mercurial, a pris la suite avec un zoom sur le mécanisme d'import. Il nous a présenté le mécanisme de recherche de module qui va au delà de la recherche de fichiers Python et permet de gérer les packages, les modules en C et les fichiers de bytecode, éventuellement optimisés. Un fois le bon fichier localisé, le loader entre jeu, crée l'objet module et l'exécute. Il a ensuite illustré ces concepts avec leur mise en application dans Mercurial. En effet, Mercurial fournit plusieurs implémentations de son module parser : une version pur Python, une version en C et une version cffi. Pour charger la bonne version en fonction de contexte d'exécution (CPython, PyPy...) il utilise un finder personnalisé. Il utilise également un loader personnalisé pour traduire à la volée du code Python 2 en code Python 3. Dans une autre présentation, Boris Feld a montré comment il utilise ces possibilité du système d'import pour patcher du code de production avec des techniques très élaborées.

Ronan Lamy, core developper de PyPy, nous a présenté cette implémentation alternative qui exécute le code Python entre 20% et 200% plus rapidement. Dans certains cas utiliser PyPy peut même être une alternative à l'écriture d'extensions en C. Il est conçu avec RPython et inclus un traceur d'utilisation d'instructions qui détermine les parties de code à compiler en code machine (JIT). Les origines de ce projet qui reçoit actuellement des financements de Mozilla remontent à 2002 avec le projet Psyco de Armi Rigo. La compilation JIT est apparue en 2009 et Python 3 est supporté depuis 2011. Il y a quelques petites choses avec lesquelles il faut toutefois être vigilant quand on utilise PyPy. Notamment il faut éviter d'utiliser __del__ et libérer explicitement ses ressources, de préférences à l'aide de blocks with car la libération est basée sur un ramasse-miettes et non sur un compteur de références. Pour faire des mesures de performances, il vaut mieux éviter de se baser sur des tests automatisés qui, par nature, risquent de ne pas déclencher la compilation JIT. On préférera utiliser le module perf plutôt que timeit. Pour le profilage, à la place de cprofile, on se tournera vers vmprof (profilage statistique) et jitviewer qui permettra de voir le code assembleur produit par la compilation JIT.

Emmanuel Leblond est revenu plus en détail sur le bytecode Python et la stack d'exécution, notamment la manière dont sont exécutées les fonctions. Il a illustré ses explications d'exemples d'utilisation du module dis :

>>> import dis
>>> def greet(x):
...     return 'Hello' + x
...
>>> dis.show_code(greet)
Name:              greet
Filename:          <stdin>
Argument count:    1
Kw-only arguments: 0
Number of locals:  1
Stack size:        2
Flags:             OPTIMIZED, NEWLOCALS, NOFREE
Constants:
   0: None
   1: 'Hello'
Variable names:
   0: x
>>> dis.dis(greet)
  2           0 LOAD_CONST               1 ('Hello')
              3 LOAD_FAST                0 (x)
              6 BINARY_ADD
              7 RETURN_VALUE

Le monde du web

Ipsha Bhidonia, stagiaire à Mozilla nous a familiarisé avec les WebPush notifications. Ce mécanisme des navigateurs web permet d'envoyer des avertissements aux utilisateurs lorsqu'un événement intéressant se produit dans une application web, même si aucun onglet n'est ouvert sur l'application en question. Elle a détaillé l’architecture et les briques techniques entrant en jeu telles que les Service Worker API, Push API et Notification API. Elle a également insisté sur le fait que les notifications doivent être utilisées avec parcimonie pour ne pas spammer l'utilisateur.

Gaël Durand nous a présenté un tour d'horizon des méthodes pour programmer les navigateurs à l'aide de Python. Il existe deux approches principales : embarquer un interpréteur Python dans le navigateur, comme le fait Brython ou bien transpiler le code Python en code interprétable pour les navigateurs, que ce soit du JavaScript comme le fait Transcrypt ou bien du WebAssembly, ce qui est la solution la plus prometteuse.

Alex Marandon de Makina Corpus a quant à lui montré certaines influences de Python sur JavaScript.

Les tests

Martin Richard, Georges Bossert, Pierre Bousquié ou encore Thierry Chappuis se sont succédés durant tout le week-end pour démontrer la nécessité d’avoir le code d'une application couvert par des tests.

En effet, qu’ils soient unitaires (bas niveau), d’intégration (haut niveau), fonctionnels ou d’acceptation, les techniques restent multiples : de l’utilisation de la bibliothèque asyncio pour le code asynchrone, à l’utilisation d'assert / mock / decorator, en passant par des méthodes de (Smart)Fuzzing pour rechercher de potentielles vulnérabilités ou encore l’usage de bibliothèques comme hypothesis pour gagner du temps en générant plus ou moins aléatoirement des jeux de tests, le panel des possibilités présentées était large et n’offre que peu d’excuses pour ne plus tester son application.

Et comme le dit Éric Bréhault : un peu de tests, c'est mieux que rien. ;)

Django

Le framework web était à l'honneur dimanche avec une introduction au développement avec Django ainsi que deux sessions consacrées à Django Rest Framework.

La première est un retour d'expérience sur la mise en place d'une API publique chez Bleemeo, solution de monitoring Cloud. Leur API expose des informations sur les serveur mais tout l'enjeu est de n'exposer que ce que les utilisateurs doivent pouvoir voir. On a ainsi pu assister à une démonstration d'utilisation et de sécurisation de DRF, avec un point sur les API d'authentification et sur l'implémentation de Django Guardian.

On notera que notre suite d'articles sur Django Rest Framework a été mentionnée pour bien débuter avec celui-ci.

La deuxième, présentée par Xavier Ordoquy, co-mainteneur de DRF a été plus dans la gestion des permissions au sein de DRF, avec une explication de la structure du module, des permissions par objet et par liste, ainsi qu'un éventail de questions fréquentes posées par la communauté qui méritaient d'être répondues.

Packaging

Julien Castet nous a présenté un certain nombre de problèmes avec le packaging Python :

  1. La gestion des dépendances multiples par pip. Si un même paquet est requis dans des versions incompatibles, pip ne détecte pas cette incohérence et se contente d'un warning noyé dans la sortie standard.
  2. python setup.py nosetests utilise easy_install qui ne gère pas le nouveau format de paquet wheel
  3. Déprécation des dependency_links qui permettaient d'installer automatiquement une dépendance depuis un dépôt de source. Désormais il faut installer cette dépendance explicitement avec un fichier requirements.txt
  4. Environnements virtuels difficilement relogeables (l'option --relocatable existe mais avec des contraintes)
  5. les système de dépôts de paquets python privés ne sont pas totalement au point.

Puis, Alexandre Galodé et Pierre-Antoine Vitel nous ont présenté le nouveau format de paquets wheel et l'outil Devpy permettant de créer un dépôt similaire à pypi.python.org mais interne et privé.

Enfin, Nicole Harris nous a présenté warehouse, la future version du dépôt pypi, utilisant des technologies et un look plus moderne.

Les dessous du portage d'Ansible à Python 3

Michael Scherer nous a fait un retour d’expérience sur les difficultés du portage d’Ansible à Python 3. Ansible est un outil de déploiement et de configuration qui se charge de copier et exécuter des modules Python sur des serveurs distants (via SSH par exemple) avant de récupérer le résultat en JSON. Le problème est que ces déploiements doivent pouvoir se faire sur tout un tas d’environnements cibles, dont certains sont encore en Python 2.4. Du coup comment aborder le problème ?

Une première piste envisagée a été de dupliquer chaque module Ansible en deux versions, une en Python 2 et une en Python 3, mais cela implique d’importants problèmes de maintenance. En effet il peut être difficile de motiver un développeur ayant fait un correctif sur la version Python 3 de le porter sur la version Python 2 et de refaire tous ses tests en double.

La bonne solution est donc d’adapter les modules pour qu’ils marchent à la fois sur Python 2 et 3 en écrivant du code compatible. Michael nous a alors présenté quelques bonnes pratiques (utilisation de six, ...), les principaux problèmes qu’il a rencontré et a beaucoup insisté sur la nécessité d’avoir une bonne couverture de tests incluant des scenarios qui fonctionnent mais aussi tous les cas d’erreurs !

IPython et le notebook Jupyter

Romuald Texier-Marcadé nous a présenté IPython et son notebook Jupiter.

IPython est un shell interactif offrant de multiples avantages par rapport au shell Python classique, avec entre autres : - Coloration syntaxique - Autocomplétion - Historique des commandes saisies mais aussi des résultats - Aide en ligne et accès au code source - Accès au commandes systèmes (ex: ls, mkdir, …) - Intégration à la boucle d’événements de divers toolkits tels que qt et gtk.

Puis vient le notebook Jupyter, une interface web interactive HTML5 qui permet de créer des notes riches et de les partager. Initialement dédié au langage Python, Jupyter permet d’intégrer à présent plus de 40 langages de programmation différents. Une note créée dans Jupyter permet d’intégrer : - Du texte riche en markdown - Des formules mathématiques avec Latex - Du code Python avec affichage du résultat - Des images, des vidéos, de l’audio - Du code Matplotlib (par exemple) et sa sortie graphique avec des possibilités d'intéractions dynamiques - etc.

Les documents créés avec Jupyter (.ipynb) sont au format JSON et peuvent donc être facilement versionnés. Par ailleurs Github intègre un visualisateur de notebook !

Enfin, un notebook peut être exporté en HTML, PDF, Mardown, RestructuredText ou sous la forme de slides.

Lightning talks

5mn pour présenter son projet, sa dernière trouvaille, ses astuces, du coup on en prend plein les yeux.

MarkdownMail

S'il y a bien une chose embêtante avec les mails, c'est qu'il faut fournir deux versions pour éviter les anti-spam : une version texte brut et une version html.

L'idée de markdownmail est de n'écrire qu'une seule fois le contenu, en markdown. La version plain_text est donc de fait lisible (puisque c'est du markdown). La version HTML est donc générée à partir du markdown, avec une option pour ajouter un peu de CSS.

https://pypi.python.org/pypi/markdownmail

RainCoat

On a tou(te)s eu un jour à surcharger une fonction très longue, donc mal découpée, pour modifier son comportement en plein milieu. Et là, pas de mystère, il faut la copier-coller... là où ça devient dangereux c'est lorsque cette fonction change, par exemple pour inclure un patch de sécurité ou lorsque des variables ou API internes (internals) sont modifiées. Comment être notifié de ce changement ?

La réponse est _raincoat_, il vous suffit de marquer votre code avec un commentaire de type :

# Raincoat: package "libtierce==14.5.7" path "malibtierce/__init__.py" "SaClasse.fonction_mal_decoupee"

Lorsque vous exécuterez raincoat, celui-ci repérera ce commentaire, et regardera si dans les prochaines versions sur PyPi le corps de la méthode a été modifié.

https://github.com/novafloss/raincoat

Woof

Envie de créer un serveur REST rapidement sans vous faire mordre ? On pourra comparer ce framework à un Flask special REST.

https://github.com/Maillol/woof

Reloadr

Ce PoC (a ne pas utiliser en production) démontre qu'on peut recharger le code d'une fonction Python à chaud, dans un autre thread.

https://pypi.python.org/pypi/Reloadr

Conclusion

Il y a bien d'autres sujets qui ont été abordés au cours de cette PyConFr : la 3D, la programmation réseau, les bonne pratiques, la place de Python dans le monde éducatif, etc. Cet article déjà fort long ne rends compte que d'une petite partie, basée sur notre perception forcément limitée, de ce qui s'est produit au cours d'un événement aussi important que PyConFr. Le vendredi soir il y avait même une soirée festive avec un conteur et un groupe de musique cubaine ! Si vous n'êtes jamais venus à PyConFr, nous vous recommandons vivement d'essayer de venir l'an prochain.

Pour conclure, il ne nous reste plus qu'à remercier l'équipe d'organisation pour son travail considérable !

L'équipe d'organisation de PyConFr 2016
ABONNEZ-VOUS À LA NEWSLETTER !
Voir aussi
Formation Python initiation à Toulouse du 18 au 20 septembre Formation Python initiation à Toulouse du 18 au 20 septembre 06/07/2017

Vous êtes développeur et maîtrisez déjà un langage de programmation ? Python vous tente et ...

Initiation au Machine Learning avec Python - La théorie Initiation au Machine Learning avec Python - La théorie 07/06/2017

Dans ce tutoriel en 2 parties nous vous proposons de découvrir les bases de l'apprentissage ...

Initiation au Machine Learning avec Python - La pratique Initiation au Machine Learning avec Python - La pratique 07/06/2017

Dans ce tutoriel en 2 parties nous vous proposons de découvrir les bases de l'apprentissage ...

Présentation de l'écosystème Python scientifique Présentation de l'écosystème Python scientifique 10/11/2016

Au fil des années Python est devenu un outil du quotidien pour les ingénieurs et chercheurs de ...

Récupérer des données Hadoop avec Python 02/05/2017

Accéder à des données situées sur un cluster Hadoop peut se faire de différentes manières en ...