Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Maintenir ses dépendances Python dans le temps

Par mis à jour le

Améliorer cette page

Une dépendance épinglée ne vieillit pas toute seule dans votre dépôt, mais le monde autour d'elle avance : de nouvelles versions sortent, des failles sont découvertes. Maintenir ses dépendances, c'est vérifier régulièrement ce que l'outil embarque, ce qui a pris du retard et ce qui est devenu dangereux, puis mettre à jour par petits pas. Cette leçon s'adresse à un Ops qui sait déjà déclarer et épingler les dépendances d'un outil Python. Elle montre comment les inventorier, les contrôler, et laisser un outil comme Dependabot ou Renovate proposer les mises à jour.

  • Distinguer les trois problèmes que pose une dépendance dans le temps.
  • Inventorier les dépendances d'un projet, directes et transitives.
  • Repérer celles en retard et celles qui portent une faille connue.
  • Mettre à jour une dépendance à la fois et relire le changement.
  • Dire ce que Dependabot et Renovate automatisent, et ce qu'ils laissent à la relecture.

Quels sont les trois problèmes d'une dépendance dans le temps ?

Section intitulée « Quels sont les trois problèmes d'une dépendance dans le temps ? »

Une dépendance pose trois problèmes distincts : l'hygiène, la mise à jour et la sécurité de la chaîne d'approvisionnement. Les confondre crée des angles morts : on croit être « à jour » parce qu'un outil ouvre des demandes de mise à jour, alors qu'on n'a jamais regardé d'où viennent les paquets installés. Le tableau les sépare, avec l'exemple de l'outil fictif inventaire-vm, qui lit un inventaire de machines en YAML. La leçon précédente en a montré le premier état ; l'exemple de cette leçon en est une variante volontairement vieillie, que la section suivante vous fait recréer.

ProblèmeLa questionExemple avec inventaire-vm
HygièneQue contient l'outil, et en a-t-il besoin ?Une bibliothèque déclarée mais plus importée nulle part
Mise à jourCombien de retard a-t-il pris ?pyyaml épinglé en 6.0.1 alors que la 6.0.3 existe
Sécurité de la chaînePeut-on faire confiance à ce qu'on installe ?Un paquet au nom presque identique à pyyaml, publié par un inconnu

Cette leçon traite l'hygiène et la mise à jour. La troisième ligne est un métier à part entière : la leçon s'arrête à un premier contrôle des failles connues, et renvoie le reste à une leçon du parcours DevSecOps (dernière section).

On inventorie un projet Python avec uv tree, qui affiche l'arbre complet des dépendances. Rappel de la leçon précédente : une dépendance directe est une bibliothèque que vous avez déclarée, une dépendance transitive est une bibliothèque que l'une d'elles tire avec elle. Seule la liste complète donne la surface réelle de l'outil. Pour suivre, recréez dans un dossier d'essai un projet qui déclare pyyaml et requests, volontairement figés sur d'anciennes versions (--vcs none évite de créer un dépôt Git, notion du module sur le travail collaboratif) :

Fenêtre de terminal
mkdir inventaire-vm && cd inventaire-vm
uv init --vcs none
uv add "pyyaml==6.0.1" "requests==2.25.1"
uv tree
inventaire-vm v0.1.0
├── pyyaml v6.0.1
└── requests v2.25.1
├── certifi v2026.7.22
├── chardet v4.0.0
├── idna v2.10
└── urllib3 v1.26.20

Deux lignes déclarées, six paquets installés : quatre bibliothèques transitives sont arrivées sans que vous les ayez choisies. Les numéros de vos sous-dépendances (certifi en particulier, qui suit la date) peuvent différer de cette sortie, datée de la rédaction. Pour un projet géré avec pip, pip list donne la liste à plat de ce qui est installé dans l'environnement actif.

L'hygiène commence ici. Une dépendance que plus aucun import n'utilise reste pourtant installée, mise à jour et auditée pour rien : retirez-la avec uv remove nom-du-paquet, qui met à jour pyproject.toml et uv.lock. Avant d'en ajouter une, demandez-vous si la bibliothèque standard de Python ne fait pas déjà le travail : chaque dépendance en plus est une ligne à maintenir. Dans le monde de la sécurité, un tel inventaire, établi dans un format normalisé, s'appelle un SBOM (la liste des composants d'un logiciel) : la page SBOM le présente.

Comment savoir quelles dépendances sont en retard ?

Section intitulée « Comment savoir quelles dépendances sont en retard ? »

L'option --outdated de uv tree ajoute, à côté de chaque paquet, la dernière version publiée. Le retard devient lisible d'un coup d'œil, sans ouvrir PyPI, l'index public où les paquets Python sont publiés :

Fenêtre de terminal
uv tree --outdated
inventaire-vm v0.1.0
├── pyyaml v6.0.1 (latest: v6.0.3)
└── requests v2.25.1 (latest: v2.34.2)
├── certifi v2026.7.22
├── chardet v4.0.0 (latest: v7.6.0)
├── idna v2.10 (latest: v3.20)
└── urllib3 v1.26.20 (latest: v2.8.0)

Les numéros de version portent une information. Dans 6.0.1, on lit majeure.mineure.correctif : un changement du dernier chiffre est en général un correctif sans risque, celui du premier chiffre peut retirer une fonction que votre code appelle. Ici, pyyaml n'a qu'un correctif de retard, tandis que urllib3 a changé de version majeure (1 vers 2). Python ne force pas cette convention, c'est une habitude très répandue : elle indique un risque, elle ne le garantit pas.

Les versions latest changent chaque jour : celles ci-dessus datent de la rédaction de la leçon, vos chiffres seront différents. Pour pip, la commande équivalente est pip list --outdated.

Comment repérer les dépendances qui portent une faille connue ?

Section intitulée « Comment repérer les dépendances qui portent une faille connue ? »

pip-audit compare les versions installées aux bases de vulnérabilités publiques et sort en code 1 dès qu'il en trouve. Une vulnérabilité est un défaut de sécurité répertorié, avec un identifiant public (PYSEC-… ou CVE-…) et la version qui le corrige. pip-audit n'est pas fourni avec uv : on l'installe une fois avec uv tool install pip-audit, ou on le lance sans installation avec uvx pip-audit. uv a aussi sa propre commande uv audit, encore expérimentale (voir uv Python) : cette leçon s'appuie sur pip-audit, l'outil établi. Le plus simple est d'exporter la liste épinglée du projet dans un fichier temporaire, hors du dépôt pour ne pas le versionner par erreur, puis de la donner à l'outil :

Fenêtre de terminal
uv export --no-hashes --no-emit-project -o /tmp/exigences-audit.txt
pip-audit -r /tmp/exigences-audit.txt

Avec uv 0.12, la première commande écrit le fichier et affiche aussi son contenu à l'écran : c'est normal. Vous y lisez une liste de paquet==version, chacune suivie d'un commentaire # via qui dit qui a demandé le paquet.

Sur le projet d'exemple, dont requests est resté en 2.25.1, la commande répondait, au moment de la rédaction, Found 24 known vulnerabilities in 3 packages ; ce chiffre est illustratif : les bases évoluent chaque jour, votre résultat sera différent. La sortie liste, pour chaque paquet, son identifiant et la version corrigée (Fix Versions). Lisez le tableau ligne par ligne : si la version corrigée existe, la réparation est une mise à jour. Le code de sortie 1 permet à un job de CI (l'intégration continue, un robot qui rejoue les contrôles à chaque modification du dépôt) de faire échouer le build, comme le montre la page Analyser et sécuriser son code Python.

Un audit ne remplace pas la mise à jour régulière : il ne voit que les failles déjà publiées dans les bases qu'il interroge. C'est un détecteur, rien de plus.

Comment mettre à jour une dépendance sans rien casser ?

Section intitulée « Comment mettre à jour une dépendance sans rien casser ? »

On change une version à la fois, on relit le diff du verrou, puis on relance les tests. La leçon précédente a montré ce geste de mise à jour ; la maintenance consiste à le répéter à intervalles réguliers. Pour rattraper le correctif de pyyaml, gardez d'abord une copie du verrou, pour pouvoir le comparer ensuite :

Fenêtre de terminal
cp uv.lock /tmp/uv.lock.avant
uv add "pyyaml==6.0.3"
diff /tmp/uv.lock.avant uv.lock

Si le projet est dans un dépôt Git, git diff uv.lock fait la même comparaison sans copie. La commande diff rend le code de sortie 1 quand les fichiers diffèrent : ce n'est pas une erreur. Le diff ne doit montrer que les lignes de pyyaml (contrainte, version, archive source et une longue liste de fichiers wheels précompilés, un par plateforme), plus ce que le paquet mis à jour exige lui-même : monter requests de 2.25 à 2.34 remplace par exemple chardet par charset-normalizer, et c'est normal. Un diff qui touche des paquets sans rapport avec celui que vous visez n'est pas la mise à jour que vous croyiez.

Reste à relancer les tests de l'outil, s'il en a : uv run pytest, une fois pytest installé par uv add --dev pytest. Ces tests disent si l'outil fonctionne encore, et le geste est l'objet de la leçon Tester une automatisation, plus loin dans ce parcours. Sur un projet qui n'a encore aucun test, uv run pytest affiche no tests ran et rend le code de sortie 5 : ce n'est pas une panne, mais une CI qui l'exécuterait échouerait. Sautez donc cette ligne tant que l'outil n'a pas de tests.

Ordre de prudence : les correctifs d'abord, les mineures ensuite, les majeures une par une en lisant les notes de version, car c'est là qu'une fonction disparaît.

Le rythme compte autant que le geste. Mettre à jour un peu chaque semaine coûte dix minutes. Attendre un an, puis tout mettre à jour d'un coup après une alerte, donne un diff énorme et une régression impossible à attribuer à un paquet.

Comment automatiser la proposition de mise à jour ?

Section intitulée « Comment automatiser la proposition de mise à jour ? »

Dependabot et Renovate surveillent vos fichiers de dépendances et ouvrent une pull request à chaque version plus récente. Une pull request est une demande de fusion relue avant d'être acceptée (voir Pull requests et code review, plus loin dans ce parcours). Vous gardez la décision : l'outil propose, les tests tournent, un humain relit et fusionne. Le guide Dependabot présente le service intégré à GitHub ; le guide Renovate présente l'outil libre qui fonctionne aussi sur GitLab, Gitea ou Bitbucket, avec une configuration plus fine.

CritèreDependabotRenovate
PlateformesGitHub uniquementGitHub, GitLab, Gitea, Bitbucket et d'autres
Mise en routeUn fichier .github/dependabot.ymlUn fichier renovate.json et une application ou un exécuteur
RéglagesFréquence, limite de PR, exclusionsRegroupements, calendrier, fusion automatique conditionnelle
Hors PythonImages Docker, GitHub Actions, Terraform (docker, github-actions, terraform)Les mêmes familles, et bien d'autres gestionnaires

Pour un dépôt hébergé sur GitHub, Dependabot est le plus court chemin. Cette configuration surveille un projet géré avec uv, une fois par semaine, avec au plus cinq pull requests ouvertes en même temps :

version: 2
updates:
- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5

Le fichier se range dans .github/dependabot.yml. L'écosystème uv est pris en charge par Dependabot en disponibilité générale depuis mars 2025 (documentation GitHub). Dès que le fichier est sur la branche principale du dépôt (la version de référence du code, notion présentée avec Git plus loin dans ce parcours), Dependabot ouvre ses premières pull requests : chacune contient le diff de pyproject.toml et de uv.lock, que vous relisez comme n'importe quel autre.

L'automatisation ne remplace pas le jugement. Une pull request automatique ne dit pas si la mise à jour casse votre outil : ce sont les tests de la CI qui répondent, et votre relecture qui tranche. Fusionner sans regarder, c'est faire confiance à ce qu'un outil a trouvé sur Internet. Les deux guides détaillent la fusion automatique des seules mises à jour à faible risque, une fois les tests solides.

Jusqu'où va cette leçon sur la sécurité de la chaîne ?

Section intitulée « Jusqu'où va cette leçon sur la sécurité de la chaîne ? »

Cette leçon s'arrête au contrôle des failles connues ; l'attaque de la chaîne elle-même est traitée ailleurs. Un paquet piégé au nom trompeur (typosquatting), un paquet interne remplacé par un homonyme public (dependency confusion), un mainteneur dont le compte est volé : aucune de ces attaques n'apparaît dans uv tree --outdated, et pip-audit ne les voit qu'après coup. Les parades (épinglage par empreinte, index privé, vérification de provenance) forment un sujet à part.

La leçon Sécuriser les dépendances npm, PyPI et Go du parcours DevSecOps les traite, mesures à l'appui. La section Sécurité de la supply chain en donne la vue d'ensemble. Pour un Ops qui débute, un réflexe suffit : n'ajoutez pas une dépendance dont vous ne connaissez ni l'auteur ni l'usage. Avant d'adopter une bibliothèque, regardez aussi sa licence (peut-on l'embarquer dans votre outil ?) et l'activité du projet ; l'outil OpenSSF Scorecard note justement ces pratiques pour un dépôt public.

  • Une dépendance pose trois problèmes : l'hygiène, la mise à jour et la sécurité de la chaîne. Cette leçon traite les deux premiers.
  • uv tree inventorie les dépendances directes et transitives ; une dépendance non utilisée se retire avec uv remove.
  • uv tree --outdated montre le retard ; le premier chiffre d'une version signale le risque d'un changement cassant.
  • pip-audit -r <fichier exporté> détecte les failles connues et sort en code 1 s'il en trouve.
  • On met à jour une dépendance à la fois, en relisant le diff de uv.lock puis en relançant les tests s'il y en a.
  • Dependabot et Renovate ouvrent les pull requests ; la CI et la relecture décident de la fusion.

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn