---
Title: Python et virtualenv avec pyenv
date: 2019-04-23 06:43
Authors: Victor
Slug: python-et-pyenv
Category: Système
Tags: python, astuces, pyenv
keywords: python, astuces, pyenv
Status: published
---

[TOC]

# Une petite introduction

[pyenv](https://github.com/pyenv/pyenv/) est un logiciel de gestion de **version python**. Ça parait simple ! Mais pourquoi me direz vous ? 

Tout ceux qui ont déjà développés avec python savent que c'est assez vite le bordel entre python 2 et python 3. La version 3 amène énormément de changement, et en conséquence cela fait des années qu'elle n'est pas massivement adoptée...  
De nombreux logiciels ne sont encore compatibles qu'avec python 2.7, et impliquent un travail de développement assez conséquent pour être compatible avec python 3, sans parler d'être compatible avec les 2 versions simultanément.

Il est donc devenu quasiment standard de posséder sur un système **2 versions de python**, la dernière 2.7 et la dernière 3.5, dans l'optique de gérer les différents logiciels selon leurs besoins.

En outre python possède un concept relativement unique et très intéressant : le virtualenv, dont vous pourrez trouver une excellente intro ici : [virtualenv - Inversion n°42 du génome](https://noskillbrain.fr/2017/12/26/virtualenv-wrappervirtualenv/).  
Ce système permet d'utiliser un environnement python dédié à un logiciel, avec ses propres librairies, afin de répondre parfaitement aux prérequis d'un logiciel, même s'il utilise des versions de librairies non inclues dans votre système.  

Tout ceci, bien que très intéressant (de mon point de vue 😂) est quand même globalement **un beau merdier**, faut dire ce qui est.  
Et en plus python a officiellement annoncé que la version 2.7 ne serait plus [supportée à échéance 2020](https://pythonclock.org/).

C'est ici qu'intervient **pyenv**, en tant que gestionnaire de version python et en bonus de virtualenv !

# Passons à l'installation

## Prérequis

Les prérequis sont listés sur le [wiki de pyenv](https://github.com/pyenv/pyenv/wiki#suggested-build-environment) et disponibles pour différents OS.

Pour les plus classiques, sous Debian : 

```bash
sudo apt-get update; sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
```

ou Fedora :

```
sudo dnf install -y make gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel
```

Notez que ces prérequis ne concernent pas l'installation de pyenv lui-même, mais ce qui est nécessaire pour l'utiliser, et notamment compiler les versions python :-)

## Installons pyenv

L'installation reste somme toute classique. Vous pouvez passer directement par le [dépôt git](https://github.com/pyenv/pyenv/#installation), ou par brew si vous utilisez Mac OSX.

Cela dit, je vous conseille d'utiliser le petit **[wrapper](https://github.com/pyenv/pyenv-installer)** réalisé par le développeur pour gérer l'installation de pyenv. En effet il présente l'avantage outre le fait d'installer pyenv, d'activer quelques **modules** bien pratiques, notamment celui permettant de jouer avec les virtualenv !

```bash
$ curl https://pyenv.run | bash
```  

Vous me direz que c'est très mal d'exécuter des scripts bash depuis le net de cette façon ! Je vous dirais que oui en effet, mais j'ai ici pris la peine de le lire, et il se contente de faire **quelques git clone**, rien de répréhensible.

Je vous invite à ne pas me faire confiance et à aller regarder par vous même 😘

Une fois le script exécuté et comme il vous invite à le faire, ajoutez dans votre fichier `~/.bashrc` les lignes suivantes si elles ne sont pas déjà présentes : 

```bash
export PATH="~/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
```

Ces lignes, exécutées à chaque ouverture d'un shell bash, vont permettre à pyenv d'insérer dans votre PATH les chemins vers toutes ses différentes versions installées.  
Vous y gagnez en plus **une auto-completion** bien pratique.


# Quoiqu'on en fait ?

Bien, pyenv est installé, et maintenant ? Maintenant, jouons mes amis, jouons !

## Versions python

De base avec pyenv, vous verrez uniquement la version python de base livrée avec votre système :

```bash
$ pyenv versions
* system (set by /home/victor/.pyenv/version)
```

Cependant, vous pouvez en installer de nouvelles très facilement. Je vous conseille à minima d'activer les versions `2.7.15` et `3.7.2`, dernières versions en date lors de **l'écriture** de cet article.  
Bien entendu, n'hésitez pas à adapter avec vos besoins et/ou les dernières versions lors de votre **lecture** de cet article 😋 

```bash
pyenv install 2.7.15
pyenv install 3.7.2
```

**Attention**, pyenv ne gère que les versions qu'il connait ! Elles peuvent différer des dernières versions sorties par les développeurs de python tant que pyenv n'aura pas été mis à jour (à la manière d'un `apt-get update`).  
Il peut aussi s'écouler un peu de temps entre la sortie d'un patch des développeurs de python et son intégration dans pyenv.

Vous pouvez lister les versions connues avec : 

```bash
pyenv install --list
```

Et vous pouvez mettre à jour pyenv avec :

```bash
pyenv update
```


Une fois vos versions préférées de python installées, vous pouvez vérifier que tout est ok :

```bash
$ pyenv versions
* system (set by /home/victor/.pyenv/version)
  2.7.15
  3.7.2
```

Le petit **asterisk** indique la version actuellement configurée par défaut.

## Virtualenv(s) 

Avec au moins une version python d'installée, on va pouvoir commencer à jouer un peu avec les **virtualenv** !  
Pour rappel, un virtualenv permet de mettre en place un environnement python isolé, où vous pourrez installer les librairies spécifiques dont vous avez besoin pour un logiciel particulier.

Mettons que comme dans l'article de [noskillbrain](https://noskillbrain.fr/2017/12/26/virtualenv-wrappervirtualenv/) vous souhaitez utiliser plusieurs versions d'Ansible.  
On peut tout simplement créer **2 virtualenv**, un pour `ansible 2.6` et un pour `ansible 2.7`, en utilisant python `3.7.2` :

```bash
pyenv virtualenv 3.7.2 ansible-26
pyenv virtualenv 3.7.2 ansible-27
``` 

J'ai ici créé 2 virtualenvs, mais ils sont pour l'instant vides :

```bash
$ pyenv virtualenvs
  3.7.2/envs/ansible-26 (created from /home/victor/.pyenv/versions/3.7.2)
  3.7.2/envs/ansible-27 (created from /home/victor/.pyenv/versions/3.7.2)
  ansible-26 (created from /home/victor/.pyenv/versions/3.7.2)
  ansible-27 (created from /home/victor/.pyenv/versions/3.7.2)
```

Et comme pyenv a le bon goût d'auto-compléter ses commandes, quelques tabulations vous permette d'activer rapidement un env :

```bash
[victor:~] $ pyenv activate ansible-26 
[victor:~] [ansible-26] $ 
```

Une fois dans votre env, vous pouvez tranquillement installer votre version d'ansible en utilisant pip :

```bash
$ pip install ansible==2.6
```

Vous pouvez également directement changer de virtualenv :

```bash
pyenv activate ansible-27
```

Ou encore sortir du virtualenv 

```bash
[victor:~] [ansible-26] $ pyenv deactivate 
[victor:~] $ 

```

# Conclusion

Comme vous le voyez, gérer un virtualenv avec pyenv est vraiment très simple (sans parler de gérer des versions python 😄).

Vous pouvez maintenant gérer vos virtualenv facilement, sans devoir ajouter des alias dans votre bashrc pour chacun d'entre eux ou vous souvenir des chemin à activer 😉.

pyenv a d'autres mécanismes sympathiques, comme la possibilité d'activer automatiquement des versions par répertoire, exécuter des logiciels avec une version spécifique, etc.  
Je n'en parlerai pas dans cette introduction, mais n'hésitez pas à parcourir le [github](https://github.com/pyenv/pyenv) du développeur et son wiki associé, plein de bonnes idées.



