Subtilités du packaging en Python

Récemment pour le développement de ma librairie Yapsy, je suis tombé sur quelques subtilités liés à la création de « paquets » pour des librairies Python.

J’utilise distutils bien sûr et je place les paquets générés sur http://pypi.python.org, mais j’avais les problèmes suivants:

  • les fichiers de données utilisés par mes tests unitaires n’étaient pas packagés
  • je n’arrivais pas à faire comprendre à pypi que l’un des paquets « sources » ne pouvait être récupéré que par les utilisateurs de Python2 alors que l’autre devait l’être par les utilisateurs de Python3, bien qu’ils correspondent tous les deux à la même version du logiciel (typiquement je n’arrivais pas à avoir ces deux paquets sur la même page de pypi.python.org)

Les solutions étaient relativement simples mais étrangement peu documentées sur internet…

La solution au premier problème me parait désormais triviale mais j’ai longtemps cherché dans la mauvaise direction: à cause de mauvaise habitude prise avec py2exe dans d’autres projets où je déclarais les fichiers de données avec un argument spécial de la fonction setup.

Par extension, je cherchais une solution purement pythonesque, pour finalement réaliser qu’il suffisait d’écrire un fichier MANIFEST.in, donc la syntaxe est très simple. La révélation est arrivée grâce au site suivant, un projet de documentation inachevé par Tarek Ziadé: The Hitchhiker’s Guide to Packaging. La section « Create package » ne laisse pas vraiment de place au doute: il faut créer un MANIFEST.in, ce n’est pas du tout un hack mais une composante normale du paquet… dont acte !

Le second problème était plus trapu et bizarrement il m’a semblé quasiment impossible de trouver (avec google) des ressources au sujet du packaging simultané pour Python 2 et 3. J’ai tout de même mis la main sur une ressource et, coup-de-bol, elle est particulièrement bien étoffée. Il s’agit tout naturellement de la page « Distribution » du site Porting to Python3

A noter que pour yapsy j’ai choisi la stratégie un peu brutale qui consiste à mettre dans un même paquet les sources pour Python2 et les sources pour Python3, et laisser le script de setup décider au moment de l’installation lequel des deux dossiers il va installer. Pour automatiser le tout j’ai eu fait un petit script shell ad hoc qu’on peut consulter aux endroits suivant: