Journal Gestion de dépendances en python

Posté par  (site web personnel, Mastodon) . Licence CC By‑SA.
Étiquettes :
2
11
nov.
2026

Sommaire

Je vous partage ici mon retour d'expérience sur la gestion des dépendances en python.

L'article original est disponible ici.

Intro

Dans le cadre de mon travail, j'ai régulièrement besoin d'écrire des scripts en python ou bien des notebook Jupyter. Je n'ai pas particulièrement d'affinité avec ce langage, disons qu'il s'est imposé à moi :-) En revanche, il y a quelque chose qui me chagrine, c'est la gestion des dépendances. C'est particulièrement agaçant de reprendre un script et de voir que les dépendances ne sont pas indiquées ou bien il manque leur version et loi de Murphy oblige, l'API a bougé… Bref, je peux lister les problématiques suivantes dans la gestion des dépendances de mes projets python:

  • lister les dépendances
  • fixer la version des dépendances
  • fixer la version des dépendances des dépendances
  • Obtenir les dépendances, comment travailler hors-ligne, que faire si pypi tombe

On peut déjà indiquer quelques solutions qui font consensus pour gérer une partie de ces problèmes. En particulier, on peut commencer par lister nos dépendances dans un fichier texte. Si vous utilisez pip pour installer vos dépendances, il dispose d'une solution standardisée: requirements.txt

Cette solution permet de résoudre nos deux premiers problèmes:

  • lister les dépendances: scipy matplotlib numpy
  • fixer la version des dépendances: scipy == 1.18.* matplotlib == 3.11.2 numpy == 2.5.4
  • fixer la version des dépendances des dépendances ---> _(oO)_/
  • Obtenir les dépendances, comment travailler hors-ligne, que faire si pypi tombe --> _(oO)_/

Cependant lorsqu'on reprend un vieux script, il arrive parfois que la version indiquée dans le fichier requirements.txt ne soit plus distribué sous format binaire par pypi. Il faut alors compiler nous-même cette dépendance. Un cas concret: si je reprends mon exemple précédent mais que je fixe numpy == 2.0.*, une version qui a un peu plus de deux ans lorsque j'écris ces lignes. Pypi ne propose plus de télécharger directement les fichiers pré-compilés (wheels). pip va donc télécharger les sources et compiler le projet sur votre ordinateur. C'est à ce moment-là que ça peut se compliquer. En effet, certain projet ont la réputation d'être difficile à compiler. Maintenant extrapolons cette situation sur toute une cascade de dépendances, et vous apercevez la profondeur du gouffre…

Rappelons-le, à la base on souhaitait simplement re-utiliser un script sur un vieux projet ;-)

Zig

Un autre langage que j'utilise régulièrement: zig, je l'apprécie pour bien des raisons et l'une d'entre elles est sa gestion des dépendances. Pour résumer trivialement (explications valable pour la version 0.16.0 et 0.17.x, ces caractéristiques sont susceptibles d'évoluer):

  • les dépendances sont listées dans un fichier texte: build.zig.zon
  • chaque dépendance est fixée sur une révision de commit ou une version donnée
  • les sources des dépendances sont téléchargées dans le répertoire zig-pkg (on peut si nécessaire les ajouter au VCS)
  • On peut spécifier un fork local d'une dépendance (c'est toujours utile en phase de dev)

Pour plus d'informations, n'hésitez pas à lire ce post: Two Package Management Workflow Enhancements.

Pourquoi je vous parle de ça ? Parque j'aimerai bien retrouver un comportement similaire pour mes scripts en python…

Dépendances Python à la Zig

La première fonctionnalité et sûrement la plus simple, la gestion d'un fork. pip gère nativement ce problème, il vous suffit d'installer la dépendance avec la commande suivante:

pip install -e path/to/project

Si votre paquet était déjà présent dans votre installation alors pip va le supprimer et ajouter le répertoire de votre projet à la liste des chemins d'import. Et c'est tout. Maintenance lorsque vous modifier votre fork en local, les changements sont directement prient en compte dans votre projet.

Récupération des dépendances

Passons maintenant à la partie récupération en local des dépendances. On commence par créer un répertoire py-pkg à la racine de votre projet. Maintenant, on va se servir de pip pour télécharger l'ensemble des dépendances dans ce répertoire:

py -m pip download --destination-directory py-pkg -r requirements.txt

pip va télécharger les fichiers wheels de l'ensemble des dépendances dans ce dossier, mais aussi des dépendances de
vos dépendances et ainsi de suite.

Attention
Less fichiers wheels sont des fichiers binaires dépendant de la
plateforme cible (car compilés). On peut toujours télécharger les sources avec la
commande py -m pip download --no-binary :all: mais la doc le déconseille, car
certain paquet sont difficiles à compiler… De plus, après avoir testé, ça ne
télécharge que la dépendance et non toutes l'arborescence de dépendances…

Configuration à partir d'une archive

Il n'est pas conseillé d'ajouter ces versions à votre VCS, car ce sont des fichiers binaires dépendants de votre plateforme, mais vous pouvez au moins les ajouter à votre archive lorsque vous taguez une nouvelle version de votre script.

Maintenant, on peut installer les dépendances de notre projet à partir de leur archive:

py -m venv .env
source .env/bin/activate
py -m pip install --no-index --find-links=py-pkg -r requirements.txt

Quelques liens utiles

Conclusion

Cette solution ne permet pas d'obtenir un fonctionnement calqué sur celui de zig. Cependant, elle permet de pérenniser l'archivage de vos scripts et de ses dépendances.
En effet, en archivant les fichiers wheel de votre projet vous vous assurez de pouvoir le réutiliser sans soucis le jour venu. Enfin, si vous disposez toujours d'un interpréteur python compatible…

Ces problèmes n'en finiront jamais ;-)

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.