|
- +++
- title = "Environnements virtuels"
- weight = 5
- +++
-
- # Environnements virtuels
-
- La solution à la question de la fin du chapitre précédent est d'utiliser un *environnement virtuel*
- (*virtualenv* en abrégé).
-
- C'est un répertoire *isolé* du reste du système.
-
- Il se crée par exemple avec la commande `python3 -m venv foo-venv`. où `foo-venv` est un répertoire quelconque.
-
- ## Aparté : python3 -m venv sur Debian
-
- La commande `python3 -m venv` fonctionne en général partout, dès l'installation de Python3 (*out of the box*, en Anglais), *sauf* sur Debian et ses dérivées [^5].
-
- Si vous utilisez Debian, la commande pourrait ne pas fonctionner. En fonction des messages d'erreur que vous obtenez, il est possible de résoudre le problème en :
-
- * installant le paquet `python3-venv`,
- * ou en utilisant d'abord `pip` pour installer `virtualenv`, avec `python3 -m pip install virtualenv --user` puis en lançant `python3 -m virtualenv foo-venv`.
-
- ## Comportement de python dans le virtualenv
-
- Ce répertoire contient de nombreux fichiers et dossiers, et notamment un binaire dans `foo-venv/bin/python3`.
-
- Voyons comment il se comporte en le comparant au binaire `/usr/bin/python3` habituel :
-
- ```
- $ /usr/bin/python3 -c 'import sys; print(sys.path)'
- ['',
- ...
- '/usr/lib/python3.7',
- '/usr/lib/python3.7.zip',
- '/usr/lib/python3.7/lib-dynload',
- '/home/dmerej/.local/lib/python3.7/site-packages',
- '/usr/lib/python3.7/site-packages'
- ]
-
- $ /home/dmerej/foo-venv/bin/python -c 'import sys; print(sys.path)'
- ['',
- '/usr/lib/python3.7',
- '/usr/lib/python3.7.zip',
- '/usr/lib/python3.7/lib-dynload',
- '/home/dmerej/foo-venv/lib/python3.7/site-packages,
- ]
- ```
-
- À noter:
-
- * Le répertoire "global" dans `~/.local/lib` a disparu
- * Seuls quelques répertoires systèmes sont présents (ils correspondent plus ou moins à l'emplacement des modules de la bibliothèque standard)
- * Un répertoire *au sein* du virtualenv a été rajouté
-
- Ainsi, l'isolation du virtualenv est reflété dans la différence de la valeur de `sys.path`.
-
- Il faut aussi préciser que le virtualenv n'est pas complètement isolé du reste du système. En particulier, il dépend encore du binaire Python utilisé pour le créer.
-
- Par exemple, si vous utilisez `/usr/local/bin/python3.7 -m venv foo-37`, le virtualenv dans `foo-37` utilisera Python 3.7 et fonctionnera tant que le binaire `/usr/local/bin/python3.7` existe.
-
- Cela signifie également qu'il est possible qu'en mettant à jour le paquet `python3` sur votre distribution, vous rendiez inutilisables les virtualenvs créés avec l'ancienne version du paquet.
-
-
- ## Comportement de pip dans le virtualenv
-
- D'après ce qui précède, le virtualenv ne devrait contenir aucun module en dehors de la bibliothèque standard et de `pip` lui-même.
-
- On peut s'en assurer en lançant `python3 -m pip freeze` depuis le virtualenv et en vérifiant que rien ne s'affiche.
-
- ```
- $ python3 -m pip freeze
- # de nombreuses bibliothèques en dehors du virtualenv
- apipkg==1.5
- cli-ui==0.9.1
- gaupol==1.5
- tabulate==0.8.4
-
- $ /home/dmerej/foo-venv/bin/python3 -m pip freeze
- # rien :)
- ```
-
- On peut alors utiliser le module `pip` *du virtualenv* pour installer des bibliothèques dans celui-ci :
-
- ```
- $ /home/dmerej/foo-venv/bin/python3 -m pip install cli-ui
- Collecting cli-ui
- Using cached https://pythonhosted.org/..cli_ui-0.9.1-py3-none-any.whl
- Collecting colorama (from cli-ui)
- Using cached https://pythonhosted.org/..colorama-0.4.1-py2.py3-none-any.whl
- Collecting unidecode (from cli-ui)
- Using cached https://pythonhosted.org/..Unidecode-1.0.23-py2.py3-none-any.whl
- Collecting tabulate (from cli-ui)
- Installing collected packages: colorama, unidecode, tabulate, cli-ui
- Successfully installed cli-ui-0.9.1 colorama-0.4.1 tabulate-0.8.3
- unidecode-1.0.23
- ```
-
- Cette fois, aucune bibliothèque n'est marquée comme déjà installée, et on récupère donc `cli-ui` et toutes ses dépendances.
-
- On a enfin notre solution pour résoudre notre conflit de dépendances :
- on peut simplement créer un virtualenv par projet. Ceci nous permettra
- d'avoir effectivement deux versions différentes de `cli-ui`, isolées les
- unes des autres.
-
- ## Activer un virtualenv
-
- Devoir préciser le chemin du virtualenv en entier pour chaque commande peut devenir fastidieux ; heureusement, il est possible *d'activer* un virtualenv, en lançant une des commandes suivantes :
-
- * `source foo-venv/bin/activate` - si vous utilisez un shell POSIX
- * `source foo-venv/bin/activate.fish` - si vous utilisez Fish
- * `foo-venv\bin\activate.bat` - sous Windows
-
- Une fois le virtualenv activé, taper `python`, `python3` ou `pip` utilisera les binaires correspondants dans le virtualenv automatiquement,
- et ce, tant que la session du shell sera ouverte.
-
- Le script d'activation ne fait en réalité pas grand-chose à part modifier la variable `PATH` et rajouter le nom du virtualenv au début de l'invite de commandes :
-
- ```
- # Avant
- user@host:~/src $ source foo-env/bin/activate
- # Après
- (foo-env) user@host:~/src $
- ```
-
- Pour sortir du virtualenv, entrez la commande `deactivate`.
-
- ## Conclusion
-
- Le système de gestions des dépendances de Python peut paraître compliqué et bizarre, surtout venant d'autres langages.
-
- Mon conseil est de toujours suivre ces deux règles :
-
- * Un virtualenv par projet et par version de Python
- * Toujours utiliser `pip` *depuis* un virtualenv
-
- Certes, cela peut paraître fastidieux, mais c'est une méthode qui vous évitera probablement de vous arracher les cheveux (croyez-en mon expérience).
|