Stella

L’enfer des paquets Python : le sac de nœuds (1 / 7)

La gestion des paquets Python est parfois un enfer. Vous ne voyez pas de quoi je veux parler ? Je vous montre deux ou trois trucs, et on en reparle après…

💕💕💕

Cet article fait partie d’une série de 7 articles larmoyants sur la création de paquets Python :

  1. Le sac de nœuds
  2. Les racines du mal
  3. La folie des formats
  4. Des fichiers partout
  5. La boîte à outils
  6. L’expression des besoins
  7. La solution minimale

Avant toute autre chose, j’aimerais faire un gros bisou à l’ensemble des membres de l’équipe PyPA. Je me plains beaucoup dans cette suite d’articles, cela ne m’empêche pas d’avoir une immense et sincère dose de respect pour le travail sisyphéen déjà accompli.

Ceci étant dit : nous voilà (re)partis pour le chouinage 😭.

💕💕💕

C’est quoi, le problème ?

Si vous êtes là, je suppose que vous avez déjà fait un peu de Python. Vous avez déjà installé un projet Python, avec des dépendances. Et pour faire tout cela, il est possible que vous ayez eu à faire certaines choses. Beaucoup de choses. Beaucoup trop de choses. Pas tant que ça ? Je parie que vous avez déjà rencontré des trucs qui s’appellent pip, pipenv, poetry, setuptools, distutils, requirements.txt, setup.py, Pipfile, setup.cfg, pyproject.toml, venv, virtualenv, wheel… Je m’arrête là, mais vous en connaissez encore d’autres, sans vous en rendre compte.

C’est trop, et ce n’est pas normal.

Mandatory Related XKCD™
Le XKCD obligatoire

Une phrase du Zen de Python dit à juste titre « There should be one− and preferably only one −obvious way to do it ». Vous le voyez, là, le problème ?

L’horreur des débuts

Vous ne vous rappelez peut-être pas, mais à un moment vous ne connaissiez pas Python. Si, si, je vous assure.

Tentez d’expliquer à quelqu’un à l’aise derrière un clavier (mais qui ne connaît pas Python) comment installer un programme Python. À sa place, en bon néophyte du XXIe siècle, je m’attendrais à quelque chose comme :

  1. Installe Python en suivant le super tuto super court de la super doc, ou à la limite avec la commande download-python-and-install-it.
  2. Installe ton programme en cliquant ici, ou à la limite avec la commande python-install mon-programme.

Désolé de casser vos rêves : ça ne se passe pas comme ça du tout. Mais alors pas du tout. Le « super tuto super court de la super doc » pour installer Python n’existe pas. Et il existe beaucoup trop de programmes python-install, tous incompatibles entre eux, dont aucun n’est fourni avec Python, pour ce que soit sympa d’installer votre programme.

Ouais : 🤦. On est d’accord.

Paye ton tuto

Si on parle de tuto, la meilleure source est sans doute à trouver du côté de The Hitchhiker’s Guide to Python. Il y a toujours beaucoup à dire sur la documentation, mais pour apporter une pointe d’optimisme : le guide est traduit en plusieurs langues, et je trouve qu’il est à certains moments vraiment bien fait et plutôt didactique.

Hide the Pain Harold
« Alors tu vois, tu peux pas faire des f-strings avec ton virtualenv parce qu’il est en Python 2 »

Je ne parlerai pas du fait que ce n’est pas la documentation officielle. Ni du fait que tout ce guide est une promotion à peine déguisée à la gloire des projets de son discutable auteur. Non, n’insistez pas, je ne déverserai pas mon fiel.

Problème : ce tuto n’est ni court, ni simple. Vous êtes sur macOS ? Voici ce qui vous attend dès les premiers paragraphes :

Avant l’installation de Python, vous devrez avoir installé GCC. GCC peut être obtenu en téléchargeant Xcode, en plus léger, Command Line Tools (vous devez avoir un compte Apple) ou bien le paquet encore plus petit OSX-GCC-Installer.

Je vous épargne l’enfer 🔥 de l’installation sous Windows, où il existe une liste démoniaque de solutions toutes plus ou moins bancales. Python est dans le Store (c’est ce que dit Microsoft), dans Chocolatey (c’est ce que dit le Hitchhiker’s Guide en anglais, mais pas en français), sur python.org (c’est ce que dit python.org, mais pas sa documentation ).

Quelle est la meilleure solution ? Je ne sais pas. En fait il n’y en a pas. Et c’est très mal.

Paye ton installeur

D’accord pour ce premier point un peu désastreux. Mais… On pourrait peut-être se rattraper sur le second point ? Installer un paquet après avoir installé Python devrait être un jeu d’enfant. On fait pip install mon-paquet, non ?

Non.

sudo pip install mon-paquet plutôt, non ?

Non. Non. Non. Non. Non. Non. Non. Non.

Pour installer un paquet, il faut créer un environnement virtuel, mais en fait pas tout le temps. Pour créer un environnement virtuel, on va utiliser un module intégré dans Python mais en fait pas tout le temps. Et après on utilisera un programme intégré dans Python mais en fait pas tout le temps. Et après le paquet s’installera, mais en fait pas tout le temps.

Si vous ne voulez pas vous prendre la tête, vous pouvez suivre ce que dit le Hitchhiker’s Guide et utiliser Pipenv (je vous laisse deviner qui a créé ce joyeux outil). Bon, bien sûr il faudra passer outre le fait que Pipenv a abandonné ses utilisateurs un an et demi avec une version cassée sans mise à jour. Il faudra fermer les yeux sur le fait que le projet est tentaculaire, englobe une quarantaine de projets dupliqués et parfois modifiés, et fait plus de 200 000 lignes de code 😱…

Hahahahahahaha. Haha. Non.

La solitude de la création de paquets

Tout ça, c’est juste quand on installe un paquet. Si vous voulez créer et distribuer un paquet, armez-vous de patience, attendez-vous à d’autres surprises en coulisses.

Diable en boîte
À chaque fois que vous croyez avoir fermé la boîte à mauvaises nouvelles, ça s’ouvre sans prévenir

Soyons francs : il existe un tuto et un guide pour apprendre à faire des paquets. Ces documents sont plutôt bien rédigés et devraient vous amener rapidement à pouvoir mettre en ligne votre bibliothèque. En théorie, on est pris par la main. En théorie.

En pratique, les choses sont beaucoup plus chaotiques. Si l’on prend seulement trois projets comme Flask, Requests et NumPy, on arrive à une liste assez importante de fichiers liés de près ou de loin à la gestion de paquets, sans compter les classiques README, LICENSE et consorts :

  • setup.py,
  • setup.cfg,
  • MANIFEST.in,
  • Pipfile,
  • Pipfile.lock,
  • tox.ini,
  • pytest.ini,
  • .coveragerc,
  • requirements.txt,
  • pyproject.toml

La mauvaise nouvelle, c’est que Python ne fournit pas d’outil pour créer un projet prêt à être distribué. Vous allez soit vous perdre dans des projets tiers qui vont faire ça à leur manière (je te regarde encore de travers, Pipenv), soit vous allez apprendre à la dure à quoi servent ces fichiers bizarres.

(Petite note amusante : setup.py, setup.cfg, requirements.txt et pyproject.toml permettent tous les quatre, entre autres, de lister des dépendances d’un projet. Ils utilisent 4 formats de fichiers différents, dont l’un n’est même pas géré par la bibliothèque standard de Python.)

Les différents tutos et aides en ligne ne vous fourniront que des informations parcellaires et souvent obsolètes. Et pour cause : les bonnes pratiques changent constamment. Les outils ont souvent été développés sans spécifications, avec de la documentation au mieux lacunaire (je pense très fort à toi, setuptools). Le monde entier propose ses idées, de nouveaux outils fleurissent régulièrement, et tout prend vite l’allure de modes frénétiques qui tombent en désuétude au bout de quelques années (voire quelque mois si vous n’avez pas de chance)…

Je vous entends d’ici défendre votre langage chéri. « Oui, mais c’est compliqué, tout ça tout ça, bla bla bla bla… ». Vous voulez pleurer ? Allez sur la doc de Cargo, le gestionnaire de paquets de Rust. La première page est la page d’installation, elle contient 136 mots (dixit wc), commandes incluses. Elle permet d’installer Rust, avec Cargo. 136 mots, c’est un de moins que le Zen de Python. Pour de vrai.

La seconde page donne tout ce qu’il faut pour créer un paquet simple, avec un outil qui crée tous les fichiers. Elle contient le code du paquet, le fichier de métadonnées, les commandes lancées et leur résultat, un arbre des fichiers et dossiers en ASCII-art. Le tout en 183 mots.

Voilà. C’est possible. Vous savez maintenant.

Et après ?

Avec Python, vous allez apprendre des choses au hasard de vos lectures en ligne, sur des blogs douteux comme celui-là. Vous allez tomber sur des solutions StackOverflow totalement dépassées, des astuces non spécifiées exploitant des détails d’implémentation qui changeront la semaine prochaine. On inclut les tests dans le paquet, ou pas ? On les met dans le module, ou pas ? On distribue un paquet source, ou pas ? On indique les versions exactes des dépendances, ou pas ? On met la doc dans un dossier à part, ou pas ? Autant de questions, et bien d’autres, pour lesquelles vous êtes dans la profonde solitude de la création de paquets.

Vous vous dites sans doute que tout est perdu, que les gens qui ont développé tout ça sont incompétents, que Python est un langage finalement pourri et irrécupérable… Pourtant, non. Nous essaierons dans les prochains épisodes de comprendre pourquoi on en est arrivé là et combien les choses ont changé toutes ces années, souvent pour le mieux. Arriverons-nous un jour à construire un joli paquet ? Bien sûr.

À suivre…