L’enfer des paquets Python : la boîte à outils (5 / 7)
La gestion des paquets Python est parfois un enfer. Pour créer, envoyer, installer des paquets, nous avons à disposition beaucoup d’outils, qui font parfois la même chose, mais pas de la même manière.
💕💕💕
Cet article fait partie d’une série de 7 articles larmoyants sur la création de paquets Python :
- Le sac de nœuds
- Les racines du mal
- La folie des formats
- Des fichiers partout
- La boîte à outils
- L’expression des besoins
- 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 😭.
💕💕💕
Des outils pour tout faire
Des bibliothèques, des scripts, des exécutables… Même en tant que simple utilisateur, il faut connaitre et tester une bonne dose d’outils avant d’utiliser un programme Python. Vous allez devoir créer un environnement virtuel pour installer des paquets. Avec le temps, vous aurez vos petites habitudes, qui changeront au gré des évolutions et des bonnes pratiques.
Nous n’allons pas vraiment parler de cela. Mais un peu quand même.
Si l’on se concentre sur la gestion de paquets, nous pouvons déterminer trois opérations spécifiques : l’installation, la création, l’envoi sur un dépôt de paquets. Chacune de ces opérations peut être découpée en de plus petites étapes, et ce serait intéressant de comprendre dans le détail comment tout cela fonctionne.
Nous n’allons pas parler de cela en détail non plus.
Ce que nous allons tenter de faire : dresser un tableau partial, superficiel, approximatif et non-exhaustif de ce que nous pouvons utiliser pour faire ces trois opérations de base. Ça n’envoie pas du rêve mais c’est déjà, mine de rien, une tâche complexe.
Nous aurons forcément à mettre un pied dans le détail de fonctionnement des opérations, nous aurons forcément à mettre un pied dans les environnements virtuels. Mais nous tâcherons de ne pas nous perdre dans des détails, sinon nous en aurions pour − au bas mot − des heures. Et vous avez mieux à faire.
Commençons donc par deux tableaux. Le premier liste les bibliothèques, utilisables par d’autres outils.
Bibliothèque | Installation | Création | Envoi |
---|---|---|---|
distutils | Oui | Oui | Non |
setuptools | Oui, basé sur distutils | Oui, basé sur distutils | Oui, jusqu’à la version 42 |
Le second tableau liste les outils, qui proposent des exécutables.
Outil | Installation | Création | Envoi |
---|---|---|---|
easy_install | Oui, distribué avec setuptools | Non | Non |
pip | Oui, inclut une copie partielle de setuptools | Oui, des wheels avec setuptools et wheel | Non |
wheel | Non | Oui, des wheels | Non |
twine | Non | Non | Oui |
pipenv | Oui, inclut une copie modifiée de pip | Non | Non |
pipx | Oui, basé sur pip | Non | Non |
poetry | Oui, basé sur pip | Oui | Oui |
flit | Oui, basé sur pip | Oui | Oui |
Ces deux tableaux ne listent que les fonctionnalités qui nous intéressent, mais certains outils font bien d’autres choses. Ce n’est donc pas la peine de les comparer bêtement selon le nombre de cases qu’ils cochent, d’autant plus que d’autres paramètres doivent rentrer en compte dans cette comparaison, y compris des petits détails tels que la qualité et la maintenabilité du code.

Et d’ailleurs, nous n’allons pas à proprement parler comparer ces outils ; nous allons plutôt présenter les trois fonctionnalités et décrire les bibliothèques et outils qui les accomplissent. Ce n’est pas la peine de bouder, je vous assure que ce sera plus simple ainsi.
Installation de paquets
Au début, lorsque la notion de paquets a été introduite dans Python en
2000, c’est distutils
qui a été chargé de créer et
installer les paquets. Nous l’avons déjà dit dans les épisodes
précédents, mais nous allons le répéter : il l’a fait sans gestion de
dépendances et sans dépôt de paquets.
distutils
est une bibliothèque qui permet avant tout
d’écrire des fichiers setup.py
, qui ont longtemps été
l’alpha et l’oméga des paquets Python. Grâce à distutils
qu’ils importent, ces fichiers sont exécutables et offrent deux
commandes : install
pour installer, sdist
pour créer le paquet. On peut dès lors partager des archives qui contiennent
l’ensemble du code, et les installer après les avoir décompressées. En
d’autres termes : ces archives sont des paquets.
L’idée d’avoir un endroit où stocker et partager ces paquets arrive
vite. PyPI est mis en ligne trois ans après l’arrivée de
distutils
; il permet de partager et de retrouver, à un
endroit public central, un grand nombre de paquets Python.
La bibliothèque setuptools
arrive en 2004 pour apporter de
nouvelles fonctionnalités, en particulier la gestion de dépendances. Au
niveau de l’installation de paquets, c’est la
révolution : easy_install
est inclus dans la bibliothèque
et permet d’installer les paquets de PyPI directement avec leur nom.
Cependant, setuptools
et easy_install
vont
eux aussi commencer à montrer leurs limites. Créés sans véritable
spécification, basés sur un format de paquets imparfait (les eggs), ils
vont attiser les volontés de remplacement.
Ce sera le cas pour easy_install
qui sera remplacé 4 ans
plus tard par pip
. pip
a pour but premier
d’installer des paquets Python en gérant correctement leurs
métadonnées, ce qui permet entre autres de lister et désinstaller les
paquets installés.
pip
a beaucoup évolué et est aujourd’hui l’application de
référence concernant l’installation de paquets. L’outil a su s’adapter
aux différentes évolutions et est aujourd’hui capable de se débrouiller
avec les paquets sources et les wheels. Son architecture réfléchie et
sa large utilisation lui ont permis d’intégrer des évolutions étape par
étape, et de rester vivant depuis plus de 10 ans.
L’outil est utilisé ou inclus dans tous les outils récents
d’installation de paquets. Si l’on prend certains outils largement
utilisés comme Pipenv
, Poetry
et
pipx
, tous lancent pip
pour l’installation de
paquets.
Alors, pourquoi utiliser d’autres outils que pip
?
Pipenv
, Poetry
, pipx
et d’autres
permettent, chacun à leur manière, de cloisonner les installations. Par
défaut, pip
installe les paquets dans un dossier central,
ce qui est assez gênant lorsque l’on veut avoir différents projets qui
utilisent différentes versions de la même bibliothèque.
Pipenv
et Poetry
offrent à peu près la même
mécanique pour l’installation : ils créent un environnement virtuel
par projet, dans lequel ils installent les dépendances. Pour cet usage,
ils se comportent en réalité comme une simple capsule autour de
pip
et venv
, avec des commandes permettant de
gérer les cas les plus simples.
pipx
a un but différent : il propose la même interface que
pip
pour installer des exécutables. Il s’arrange
automatiquement pour créer un environnement virtuel par exécutable, et
pour rendre cet exécutable accessible à l’utilisateur. Il est donc plus
adapté aux utilisateurs finaux qu’au développeurs, cibles privilégiées
de Pipenv
et Poetry
.
Une dernière chose étonnante au sujet de pip
: il crée
désormais des paquets, pour pouvoir mieux les installer. Pourquoi ? Il
vous faudra lire la suite…
Création de paquets

Oui, vous avez bien lu : pip
crée désormais des paquets.
Avec la volonté sous-jacente de
se séparer de setuptools
et des autres formats de paquets, pip
se transforme
doucement en un simple installeur de wheels. Lorsqu’il a devant lui un
paquet source, il tente désormais de transformer ce paquet source en
wheel avant de l’installer, au lieu de passer par l’installeur
de setuptools
.
Ce système comporte de nombreux avantages. Tout d’abord, cela signifie
qu’à terme pip
pourrait n’être qu’un installeur de wheels
(qui est le format le plus simple à installer) couplé à un
transformateur de paquets source en wheels. Un tel fonctionnement
simplifierait grandement le code source de pip
, qui
aujourd’hui fait beaucoup d’autres choses, dont installer des paquets
depuis les sources en utilisant setuptools
.
Il faut également souligner le fait que, pour créer des paquets, il
n’est désormais plus nécessaire d’utiliser setuptools
.
D’autres outils existent pour générer un paquet source ou un paquet
wheel. Cela signifie que, de la création à l’installation, on commence
à entrevoir le bout du tunnel : il est possible d’utiliser des outils
relativement simples, basés en grandes partie sur des spécifications,
qui n’ont pas à gérer l’ancienneté que trimballe
setuptools
avec lui.
Poetry
et Flit
sont sur ce point-là assez
proches. Les deux sont capables de créer des paquets sans
setuptools
et donc sans fichier setup.py
.
Suivant les PEP
517 et
518,
utilisant le fichier
pyproject.toml
comme unique source d’information, ils
proposent une solution alternative pour créer des paquets source et des
wheels classiques, installables par pip
.
Flit
ne fait à peu près que cela. Il contient également de
quoi installer un paquet avec pip
et par liens
symboliques, ce qui est utile pour le développement.
Poetry
est beaucoup plus complet : il propose comme
Pipenv
la création d’environnements virtuels utiles pour
le développement.
Bien sûr, le passage d’un fichier setup.py
en Python à un
fichier pyproject.toml
limite les possibilités. Malgré les
efforts de ces outils pour proposer une grande flexibilité, il n’est
pas possible de faire tout ce que l’on pouvait faire avec
setuptools
, laissant à l’honorable bibliothèque le soin de
gérer les cas complexes dont la plupart ne sont que le résultats
d’esprits malades relevant plus de la psychiatrie que de
l’informatique.
Envoi de paquets
De la même manière, Poetry
et Flit
proposent
tous deux l’envoi de paquets sur PyPI ou sur des serveurs compatibles.
Cette fonctionnalité ne nécessite guère que de suivre les APIs HTTP
proposées par PyPI, et peut sembler assez simple au premier abord.
Cela n’a cependant pas toujours été le cas. setuptools
a
longtemps proposé une commande pour envoyer les paquets, non sans
problèmes. Afin d’assurer une compatibilité avec toutes les versions de
Python, il a fallu jongler avec les versions de protocoles TLS
supportées, les failles de sécurité, les mots de passe… Et bien sûr, ce
qui devait rester assez simple s’est vite transformé en triste
cauchemar de soupe de code indigeste.
Pour régler ce problème, le projet Twine
a été
développé. Twine
a comme unique but d’envoyer les paquets
sur PyPI, et de le faire bien. Il propose en bonus la possibilité de
stocker le mot de passe dans le gestionnaire de mots de passe du
système, plutôt qu’en clair dans un fichier texte comme le
proposait setuptools
. Autre détail : Twine
envoie tels quels les fichiers générés par l’outil de créations de
paquets. Cela peut paraître comme la moindre des choses, mais il faut
savoir que setuptools
recrée le paquet avant de l’envoyer,
compliquant grandement les tests.
On résume (enfin, on essaie)
Il y eut une longue période de dépendance à setuptools
,
ses incompréhensibles fichiers de configuration, son implémentation qui
fait foi, son architecture vieillissante et ses commandes discutables. Mais
cette époque est bientôt révolue, et d’autres solutions existent d’ores
et déjà pour créer et envoyer ses paquets.
Nous sommes dans une période d’incertitudes. Il est difficile, voire impossible, de savoir quels outils seront utilisés demain. Il est difficile de construire des paquets avec une architecture qui résistera à l’épreuve du temps. Mais une chose est sûre : nous avons plus de libertés et de possibilités que jamais.
Après tout, avoir de nombreux outils pour créer les paquets n’est pas un mal en soi, tant qu’ils créent tous des paquets interopérables, installables par les mêmes outils. On n’a pas les mêmes besoins lorsqu’on crée un tout petit paquet en Python pur dans son coin, ou un paquet contenant du C destiné à toutes les plateformes.
À ce sujet Flit
propose
une vision intéressante :
« Rendre faciles les choses faciles, et possibles les choses difficiles », telle est une vieille devise de la communauté Perl. Flit se concentre uniquement sur la partie « choses faciles », et laisse les choses difficiles aux autres outils.
(On en arrive à s’inspirer de la communauté Perl, tout est possible…)
Tout dépend de ce que l’on veut faire. Et ça tombe bien : c’est ce que nous verrons dans le prochain article !