Première rédaction de cet article le 10 décembre 2011
Je sais, je ferais mieux d'être constructif, au lieu de râler, et de dire du mal des autres programmeurs. Mais c'est trop énervant, il faut que je me défoule : lorsqu'on écrit un programme en Python, et qu'il dépend de plusieurs paquetages (dont certains peuvent être installés et d'autres pas), c'est très galère. Il n'existe aucun mécanisme standard pour indiquer dans la distribution quels paquetages sont nécessaires.
Démonstration avec la bibliothèque seenthis-python, qui permet d'accéder au service de court-bloguage et de partage de liens SeenThis. seenthis-python dépend de deux paquetages, SimpleTAL, un système de gabarits, pour générer du XML propre, et FeedParser, pour analyser les messages en Atom que renvoie SeenThis. Dans la distribution de seenthis-python, comment indiquer (à part par du texte libre dans le README) qu'on dépend de ces paquetages ?
Commençons par le grand classique, car c'est le seul distribué avec
Python, dans la bibliothèque standard, et sur lequel tout le monde
peut compter : distutils. Le principe
est qu'on écrit un fichier setup.py
qui va
indiquer un certain nombre de choses sur le programme :
from distutils.core import setup setup(name='SeenThis', version='0.0', description='Use the SeenThis API', license='BSD', author='Stephane Bortzmeyer', author_email='stephane+seenthis@bortzmeyer.org', url='https://github.com/bortzmeyer/seenthis-python', )
Ce fichier peut ensuite être exécuté avec des options qui vont dire
par exemple d'installer le paquetage (python setup.py
install
) ou de l'enregistrer dans le Python Package Index (PyPI) (python setup.py register
).
distutils a des tas de limites. Par exemple, il ne permet pas de
faire des eggs, des paquetages binaires pour
Python. Mais, surtout, il ne permet pas d'exprimer des dépendances :
aucun moyen dans le script ci-dessus de dire qu'on a besoin de
SimpleTAL et de FeedParser. Le script setup.py
s'exécutera et installera la bibliothèque, même si les pré-requis
manquent. En lisant la
documentation, on a l'impression qu'on peut ajouter :
requires=['SimpleTAL', 'FeedParser']
mais c'est purement décoratif. La documentation ne le dit pas mais cette variable est complètement ignorée par distutils.
Au passage, le langage d'expression des dépendances (qui ne sert à
rien, on l'a vu) permet également d'indiquer un numéro de version, par
exemple le fait que, pour FeedParser, en raison de la
bogue #91 (« sgmllib.SGMLParseError: unexpected
'\xe2' char in declaration
»), il faut au moins la version 5.
Lorsque le débutant en Python se plaint de cet état de chose, les vieux experts blanchis sous le harnais lui rétorquent que tout le monde le sait, et que personne n'utilise le système standard (alors, pense le débutant naïf, pourquoi est-ce que ce truc reste dans la bibliothèque standard ?). Et c'est là que les choses se compliquent, car il existe plusieurs remplaçants possibles.
D'abord, le premier, setuptools (le
lien pointe vers PyPi puisque, à partir de là, on n'est plus dans la
bibliothèque standard, ce qui oblige l'utilisateur qui va installer
la bibliothèque à installer un autre programme d'abord, alors que le
but était de lui simplifier la vie). Il existe une bonne documentation pour débutant. En gros, on remplace la
première ligne de code du setup.py
par :
from setuptools import setup
et on a alors des fonctions et variables supplémentaires comme
install_requires
qui permet d'indiquer des
dépendances. Tout content, le programmeur Python naïf édite le README
pour indiquer à ses futurs utilisateurs qu'il va falloir installer
setuptools d'abord avant de faire le python setup.py
build
. Mais il va vite être déçu : même si SimpleTAL est
installé, le setup.py
va tenter de le télécharger
(et échouer, car il n'est pas dans PyPi). En effet, setuptools ne
teste pas si un module Python donné est disponible (import
simpletal
), il regarde s'il y a un egg du même
nom. Ce qui n'est pas le cas. Les dépendances de setuptools sont donc
vers les eggs, pas vers les modules, ce qui ôte une
bonne partie de leur intérêt.
D'autant plus que, on l'a vu, des paquetages fréquemment répandus, comme SimpleTAL, ne sont pas forcément disponibles dans PyPi... (SimpleTAL est arrivé plus tard.)
Bon, troisième tentative : distribute, qui prétend remédier aux problèmes de setuptools. Il reprend en partie son nom (ce qui contribue beaucoup à la confusion des programmeurs, par exemple le paquetage Debian de distribute se nomme setuptools) :
from distribute_setup import use_setuptools use_setuptools() from setuptools import setup [puis setup.py comme avant]
Comme setuptools, il permet de déclarer des dépendances, mais il les gère tout aussi mal :
# python setup.py install ... Searching for simpletal Reading http://pypi.python.org/simple/simpletal/ Reading http://www.owlfish.com/software/simpleTAL/index.html No local packages or download links found for simpletal error: Could not find suitable distribution for Requirement.parse('simpletal') % python Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import simpletal >>>
(La dernière commande montre que SimpleTAL est pourtant bien installé.)
Bref, on a trois systèmes concurrents et dont aucun ne permet d'assurer une tâche aussi simple que « vérifie que simpletal est bien disponible ». Pire, rien dans la documentation n'indique leurs limites. Ainsi tous les programmeurs Python semblent savoir que distutils est très limité mais cela n'apparaît pas dans la documentation de la bibliothèque standard. Et ce n'est pas fini. Comme l'écrit Victor Stinner «Le packaging Python est une série à la Dallas avec ses drames et ses rebondissements. Le dernier événement marquant est que la réécriture de distutils, "distutils2", a été intégrée dans Python 3.3 sous le nom "packaging". Sa version pour Python 2.5 - 3.2 sera maintenue en dehors de Python sous le nom "distutils2". » Il y a aussi des compétiteurs comme Bento ou plus exotiques comme zc.buildout.
Le problème du packaging Python est discuté avec bien plus de détails techniques (et moins de râleries pas constructives) dans l'excellent article Python packaging de Tarek Ziadé dans le livre Architecture of Open Source Software, (co-dirigé par Greg Wilson et Amy Brown).
Un petit truc : si on veut regarder la variété des fichiers
setup.py possibles, on peut demander
à Google (ici, en se limitant à ceux qui contiennent requires
).
Pour terminer, une bonne série de lectures, due à Nicolas Chauvat :
Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)
Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)