Je pense que vous devez parfois contribuer à des projets python prenant en charge plusieurs versions de Python.
Vous voulez tester votre développement avec la dernière version de python, et ce, sans détruire votre environnement de dev !
Alors comment installer facilement toutes les versions de python dont vous avez besoin ?
pyenv est l'outil qui va vous permettre de gérer plusieurs versions de python sur la même machine Linux. Je l'ai intégré à mon environnement de dev. Vous verrez à la fin du billet qu'on peut l'utiliser pour installer plusieurs versions d'Ansible.
Installer pyenv
Avant d'installer pyenv, il est nécessaire d'installer des dépendances. Ces dépendances sont nécessaires, car pyenv compile la version Python cible à partir des sources.
Installation des dépendances
Sur Ubuntu / Debian
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev \
libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python3-openssl
Sur Fedora / CentOS / RHEL
sudo yum install zlib-devel bzip2 bzip2-devel readline-devel sqlite \
sqlite-devel openssl-devel xz xz-devel libffi-devel gcc make
sur Alpine
C'est surtout pour l'installer dans vos containers.
apk add libffi-dev ncurses-dev openssl-dev readline-dev \
tk-dev xz-dev zlib-dev
Pour les autres environnements
Je vous renvoie à la documentation officielle
Installation
Le plus simple pour installer pyenv est d'utiliser le projet pyenv-installer. C'est un script en ligne.
curl https://pyenv.run | bash
Une fois terminé il suffira d'ajouter ces lignes à votre fichier .bashrc
ou
.zshrc
.
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
Utilisation de pyenv
Maintenant que pyenv est installé, vous pouvez installer plusieurs versions de python sur votre machine Linux.
Lister les versions disponibles
Pour obtenir la liste des versions 3 de Cpython disponibles :
pyenv install --list | grep " 3\.[789]"
3.7.0
3.7-dev
3.7.1
3.7.2
3.7.3
3.7.4
3.7.5
3.7.6
3.7.7
3.7.8
3.7.9
3.7.10
3.8.0
3.8-dev
3.8.1
3.8.2
3.8.3
3.8.4
3.8.5
3.8.6
3.8.7
3.8.8
3.8.9
3.8.10
3.9.0
3.9-dev
3.9.1
3.9.2
3.9.3
3.9.4
3.9.5
Il est aussi possible d'installer des versions de :
- Anaconda
- ActivePython
- GraalPython
- IronPython
- Jython
- MicroPython
- MiniConda
- PyPy
- Pyston
- stackless
Installer / Desinstaller une version de python
Pyenv permet d'installer de desinstaller les versions de python avec les
commandes install
et uninstall
. L'installation prend du temps puisqu'il
compile la version demandée.
pyenv install -v 3.7.2
Lister les versions de python disponibles
pyenv versions
* system (set by /home/bob/.pyenv/version)
3.7.2
3.8.3
3.9.1
Utiliser en local une version de python
Dans un répertoire spécifique il est possible d'utiliser une version de python. Ça se fait au moyen de la commande local :
python --version
Python 3.9.1
pyenv local 3.8.3
python --version
Python 3.8.3
cd ..
python3 --version
Python 3.6.8
cd test-pypi
python --version
Python 3.8.3
Pour identifier la version locale :
pyenv versions
system
3.7.2
* 3.8.3 (set by /home/bob/Projects/test-pypi/.python-version)
Gestion des environnements virtuels python avec pyenv
Pyenv permet de gérer également les environnements virtuels de python. Pour rappel ça permet de cloisonner les différents environnements de développements.
Par exemple installons deux environnements utilisant deux versions de python différentes :
pyenv virtualenv 3.9.1 venv-391
pyenv virtualenv 3.8.3 venv-383
Ces environnements sont créés dans le répertoire ~/.pyenv/versions
donc attention
à bien leur donner des noms différents. nom-du-projet_version par exemple.
Pour lister les environnements virtuels, c'est la commande virtualenvs
avec un
s
:
pyenv virtualenvs
3.8.3/envs/venv-383 (created from /home/bob/.pyenv/versions/3.8.3)
3.9.1/envs/venv-391 (created from /home/bob/.pyenv/versions/3.9.1)
venv-383 (created from /home/bob/.pyenv/versions/3.8.3)
venv-391 (created from /home/bob/.pyenv/versions/3.9.1)
Pour activer un environnement :
pyenv activate venv-383
(venv-383) [bob@bob test-pypi]$
Pour le désactiver :
(venv-383) [bob@bob test-pypi]$ pyenv deactivate
Pour le détruire:
(venv-383) [bob@bob test-pypi]$ pyenv virtualenv-delete venv-383
Ansible et pyenv
Vous avez développé vos propres filtres, modules Ansible et bien pyenv va vous permettre de valider que ceux-ci fonctionnent avec les différentes versions d'Ansible combiné aux différentes versions de python.
Il suffira de créer différents environnements virtuels combinant toutes les versions possibles :
- ansible27-python27
- ansible29-python39 ...
Utilisation conjointe avec pipenv
pipenv permet de gérer les dépendances d'un projet python avec la même
souplesse que celle que l'on connait avec npm
via le fichier Pipfile
:
Installation de pipenv
Il suffit de l'installer avec pip
:
pip install --user pipenv
Pipenv et pyenv
Si vous avez activez un environnement virtuel et si vous lancez la commande
pipenv install
, pipenv va détecter qu'il est déjà dans un environnement
virtuel et ainsi ne va pas en créer un.
(ansible-3.8.3) [bob@bob test-pypi]$ pipenv install --dev ansible==2.9.2
Installing ansible==2.9.2...
Adding ansible to Pipfile's [dev-packages]...
✔ Installation Succeeded
Pipfile.lock (d42c91) out of date, updating to (1bdb4d)...
Locking [dev-packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Updated Pipfile.lock (1bdb4d)!
Installing dependencies from Pipfile.lock (1bdb4d)...
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
(ansible-3.8.3) [bob@bob test-pypi]$ cat Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
[dev-packages]
ansible = "==2.9.2"
[requires]
python_version = "3.8"
pipenv permet de gérer plusieurs sources. Par exemple pour ajouter votre
propre serveur pypi
tournant sous nexus
:
[[source]]
url = "https://artefacts.robert.local/repository/pypi-all/simple/"
verify_ssl = true
name = "myartefacts"
[packages]
django = "*"
my-private-app = {version="*", index="myartefacts"}
Conclusion
Ces deux outils apportent toute la souplesse que l'on attend pour pouvoir développer sereinement des projets python, mais aussi devops.