Un petit retour d’expérience sur pip
Il y a deux features qui sont très discutées autour de pip. La première c’est l’ajout d’une option upgrade all permettant de mettre à jour tous les packages pip installés (issue #59 datant du 15/03/2011). La seconde (issue #988 datant du 11/06/2013) découle de la première. Pour mettre à jour correctement tous les packages pip installés, il faudrait un gestionnaire de dépendances (ce que fait apt par exemple).
Je souhaitais vous illustrer les problématiques qu’on peut avoir autour de cela.
Pip et pip3
J’utilise Glances et Borg sur l’ensemble de mes serveurs Debian. Il se trouve que de nouvelles releases sont sorties récemment, j’ai donc voulu mettre à jour mes serveurs en conséquence. Je lance une commande Ansible pour mettre à jour Glances sur l’ensemble de mes serveurs, ça fonctionne pour quelques-uns, ça échoue pour une majorité. Je commence à creuser et je m’aperçois que sur certains serveurs j’ai installé Glances avec pip3 install glances
et sur d’autres pip install glances
. Comme on peut le voir sur la page Python Package Index (pypi), Glances peut être utilisé aussi bien avec Python 2 qu’avec Python 3. On notera également que dans l’ensemble de la page on ne parle que de pip install (et jamais pip3 install).
J’ai un choix à faire, je me dis que je vais dorénavant utiliser Glances avec Python 3. J’installe donc Glances pip3 install glances
sur tous mes serveurs puis j’en lance un au hasard. Je me rends compte qu’il utilise Python 2… En effet je me retrouve avec des serveurs sur lesquels j’ai donc fait pip install glances
ET pip3 install glances
. Il suffit de faire un petit pip list
puis pip3 list
pour se rendre compte que j’ai le package Glances installés dans les deux.
Je décide donc de supprimer Glances de Python 2 avec pip uninstall glances
. Je lance la commande glances… commande introuvable. Et oui ! Finalement un pip3 uninstall glances
suivi d’un pip3 install glances
fera comprendre au système qu’il faut utiliser Glances avec Python 3.
La morale de cette histoire c’est que je vous invite à vous méfier de ce que vous avez installé avec pip et avec pip3. Il suffit d’une erreur d’inattention une fois et vous pouvez vous retrouver avec le même package en Python 2 et Python 3 installé. Les commandes à avoir en tête pip list
et pip3 list
. Je vous rappelle également mon Mémo pip (que je maintiens à jour).
L’erreur récurrente que je fais au boulot est de balancer un petit pip install --upgrade glances
qui installera la dernière version de Glances en Python 2 alors qu’il n’était pas installé en Python 2. En effet pip considère pip install --upgrade glances
de la même manière que pip install glances
n’affichant aucun message et installant le package. Si l’option upgrade all existait, je ferais un pip upgrade all et un pip3 upgrade all ainsi je ne tomberais pas dans l’erreur pip install --upgrade glances
.
Un autre exemple mais à la maison, je me suis souvent arraché les cheveux à cause de youtube-dl et mps-youtube. Le package youtube-dl est disponible sur Python 2 et Python 3. Le package mps-youtube n’est disponible que sur Python 3 et nécessite le package youtube-dl pour fonctionner. Si vous suivez la documentation de youtube-dl vous allez faire pip install youtube-dl
puis vous ferez après pip3 install mps-youtube
. Là vous allez avoir un problème car mps-youtube ne va pas fonctionner puisqu’il cherchera youtube-dl dans Python 3. Au final il faut faire pip3 install youtube-dl mps-youtube
. Si le gestionnaire de dépendances existait, pip3 install mps-youtube
installerait automatiquement youtube-dl dans Python 3 et on n’aurait pas toute cette complexité au niveau de la compréhension et de l’utilisateur final.
Pourquoi mettre à jour tous les packages pip installés est une mauvaise idée
Je passe à présent à la mise à jour de borgbackup. J’ai un problème de dépendance ! Un peu échaudé par tout ça je commence à en avoir marre et je me dis que c’est une bonne excuse pour tester la commande pip list --outdated | cut -d' ' -f1 | xargs -n1 pip install --upgrade
citée dans mon Mémo pip à titre d’information mais que je déconseille d’utiliser qui met à jour tous les packages pip installés. La commande fonctionne très bien, elle met à jour tous les packages sauf un. Je lance alors la même commande pour pip3 (borgbackup n’est disponible que sur Python 3) et la mise à jour de borgbackup réussit.
Le lendemain je lance Ansible qui refuse de fonctionner… Ansible nécessite une version de Jinja2 inférieure à la 2.9. Ma super commande d’hier a installé la dernière version de Jinja2, la 2.9.5. Je désinstalle Jinja2 pip uninstall jinja2
puis j’installe une version au hasard inférieure à la 2.9 pip install jinja2==2.8
. Ansible fonctionne.
Vous avez un exemple de pourquoi il ne faut pas mettre à jour tous les packages pip installés parce qu’il n’y a pas de gestionnaire de dépendances semblable à apt.