Un environnement virtuel en Python : isoler les dépendances d'un projet

Un environnement virtuel donne à chaque projet Python son propre jeu de bibliothèques, pour que la mise à jour de l'un ne casse jamais l'autre.
7 min de lecture
Believemy logo

Définition

Deux projets sur le même ordinateur, l'un qui réclame la version 2.20 d'une bibliothèque, l'autre la 2.31 : installées au même endroit, ces deux versions ne cohabitent pas, et la dernière arrivée casse le projet qui fonctionnait la veille. L'environnement virtuel existe pour ce problème précis.

C'est un dossier qui contient sa propre copie de l'interpréteur Python et son propre répertoire de paquets. Tant qu'il est activé, pip install écrit dedans, et import y cherche ses modules avant d'aller voir ailleurs. Le reste de la machine ignore son existence, et deux projets voisins gardent chacun sa version.

Trois commandes suffisent à en créer un et à s'y installer.

BASH
# Crée le dossier .venv à la racine du projet
python -m venv .venv

# Bascule ce terminal dans l'environnement
source .venv/bin/activate

# Installe requests dedans, et nulle part ailleurs
pip install requests

Activer ne fait rien de magique : le dossier passe en tête du chemin de recherche, et pour ce terminal seulement.

Sur Windows, l'activation s'écrit .venv\Scripts\activate. Le nom du dossier est libre, mais .venv s'est imposé : les éditeurs le repèrent seuls et les fichiers d'exclusion de Git le connaissent déjà.


Le problème qu'il résout

Sans lui, tout s'installe au même endroit : le répertoire de paquets de l'installation Python du système, partagé par tous les projets de la machine. Une seule version de chaque bibliothèque y tient à la fois.

Et cette version revient au dernier qui installe. Mettre à jour requests pour le projet du jour la met à jour pour tous, si bien que le projet écrit six mois plus tôt hérite d'une bibliothèque qu'il n'a jamais vue. Rien ne prévient, et la panne surgit trop loin de sa cause pour qu'on l'y relie.

Deux projets sur une même machine, avec et sans environnement virtuelSans environnement virtuel, les deux projets visent la même installation : la version demandée par le second écrase celle du premier, qui ne démarre plus. Avec un environnement virtuel, chaque projet garde sa version dans son dossier, et la mise à jour de l'un n'atteint pas l'autre.Sans environnement virtuelun projet casseProjet Aattend requests 2.20ne démarre plusProjet Battend requests 2.31fonctionneUne seule installation pour toute la machinerequests 2.31 : B écrase la version de AAvec un environnement virtuelaucun ne casseProjet A.venvrequests 2.20Projet B.venvrequests 2.31la mise à jour de l'un n'atteint pas l'autre

Les deux situations se comparent sur quatre points, et le plus important n'est pas le premier.

Sans environnement virtuelAvec
Une seule version de chaque bibliothèqueUne version par projet
Les dépendances réelles du projet restent flouesLe dossier les liste exactement
Une installation peut casser un projet voisinLe rayon d'action se limite au dossier
La machine du collègue ne reproduit pas la même choseUn requirements.txt suffit à la reconstituer

Le deuxième point pèse autant que le premier : un projet dont les dépendances vivent dans l'installation générale emprunte tôt ou tard un package installé pour tout autre chose, sans que personne le remarque. Il tourne là où il a été écrit, et manque à l'appel le jour du déploiement. Un environnement virtuel ne fait donc pas qu'isoler, il révèle.

Bon à savoir

Sur beaucoup de systèmes récents, pip refuse même d'installer hors d'un environnement virtuel et répond externally-managed-environment. Ce n'est pas une panne : c'est l'installation du système qui se protège.


Ce qu'il n'isole pas

C'est de là que viennent la plupart des déceptions : le mot « environnement » promet plus qu'il ne livre. Un environnement virtuel isole les paquets Python, et rien d'autre.

Il ne fige pas la version du langage : elle est héritée de l'interpréteur qui a servi à le créer, que le dossier désigne sans le contenir. Une mise à jour du système peut donc le rendre inutilisable du jour au lendemain, et la seule issue est de le recréer.

Il n'embarque pas non plus les bibliothèques système dont dépendent certains paquets compilés, ni les variables d'environnement, ni la base de données. Faut-il alors passer à Docker ? Non : un environnement virtuel n'est pas un conteneur, il répond à la question plus étroite des dépendances déclarées sur PyPI, pour un coût proche de zéro.


L'erreur classique de ceux qui le découvrent

Le symptôme est toujours le même : une ModuleNotFoundError sur une bibliothèque installée cinq minutes plus tôt. Elle est bien quelque part sur le disque, mais pas là où le programme la cherche.

Deux gestes produisent ce résultat. Installer sans avoir activé, et le paquet part dans l'installation générale. Activer dans un terminal puis lancer le programme depuis un autre, et la seconde fenêtre ignore tout de l'environnement.

Deux commandes tranchent la question sans avoir à deviner.

BASH
# Quel interpréteur ce terminal utilise-t-il ?
which python

# Et à quel Python ce pip est-il rattaché ?
pip -V

Si les chemins affichés ne passent pas par le dossier du projet, l'environnement n'est pas actif. Un cas déroute plus longtemps : les éditeurs ont leur propre réglage d'interpréteur, et un script lancé depuis l'éditeur peut ignorer l'environnement activé dans le terminal d'à côté.


Ce qui se partage, ce qui se jette

Un environnement virtuel ne se déplace pas, il se reconstruit : les chemins écrits à l'intérieur sont absolus et désignent une machine précise.

Attention

Renommer ou déplacer le dossier du projet suffit à casser l'environnement qu'il contient : les scripts d'activation pointent toujours vers l'ancien chemin, et l'erreur affichée n'en dit rien. Supprimez le dossier et recréez-le.

Pour la même raison, verser un environnement virtuel dans Git est une fausse bonne idée : il pèse lourd et ne fonctionnera chez personne d'autre. Ce qui voyage, c'est la liste des paquets installés.

BASH
# Sur votre machine : noter les paquets installés
pip freeze > requirements.txt

# Sur une autre machine : reconstruire à l'identique
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

pip freeze relève tout ce qui est présent, dépendances de vos dépendances comprises, avec leur version exacte. Deux machines qui partent du même requirements.txt obtiennent le même jeu de bibliothèques, et un environnement abîmé cesse d'être un incident : il se supprime et se recrée sans rien perdre.


venv, virtualenv, Poetry, conda

Plusieurs outils répondent au même besoin. La bonne question n'est pas lequel est le meilleur, mais lequel apporte quelque chose que votre projet réclame vraiment.

OutilCe qui le distingue
venvLivré avec Python, décrit par la PEP 405, suffisant dans la grande majorité des cas
virtualenvL'ancêtre externe, plus rapide et compatible avec de vieilles versions du langage
poetryGère l'environnement et le verrouillage des versions dans un seul outil
condaInstalle aussi des dépendances hors Python, courant en calcul scientifique

Commencer par venv reste le bon réflexe : il est déjà là, et changer d'outil plus tard coûte peu, puisque la liste des dépendances, elle, se transporte.


Questions fréquentes

Question

Faut-il un environnement virtuel pour un script de dix lignes ?

Si le script n'utilise que la bibliothèque standard, il n'y a rien à isoler et la réponse est non. Elle devient oui dès la première commande pip install : ce paquet s'installe quelque part, et ce quelque part servira aussi à tous les projets suivants.

Question

Que faire quand l'environnement semble cassé ?

Le supprimer, puis le recréer à partir du fichier requirements.txt. C'est un dossier jetable, et une réinstallation propre règle la moitié des problèmes de dépendances plus vite que le moindre diagnostic.

Question

Un environnement par projet, ou un seul pour toute la machine ?

Un par projet, faute de quoi le problème d'origine revient intact. Seule exception raisonnable : les outils en ligne de commande employés partout, comme ruff ou un formateur de code, qui ne dépendent d'aucun projet et gagnent à être installés à part, avec pipx.

Termes connexes

Découvrez notre glossaire Python

Parcourez les termes et définitions les plus couramment utilisés dans le domaine du développement avec Python.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.