1. Introduction à Distutils

Ce document traite de l’utilisation de Distutils pour distribuer des modules Python, en se concentrant sur le rôle de développeur/distributeur : si vous cherchez des informations sur l’installation de modules Python, vous devriez vous référer au chapitre Installation des modules python (Version historique).

1.1. Concepts et Terminologie

Utiliser Distuils est assez simple, à la fois pour les développeurs de module et pour les utilisateurs/administrateurs qui installent des modules tiers. En tant que développeur, vos responsabilités (en plus d’écrire du code solide, bien documenté et bien testé, bien entendu !) sont :

  • écrire un script d’installation (setup.py par convention) ;

  • (optionnel) écrire un fichier de configuration pour l’installation ;

  • créer une distribution source ;

  • (optionnel) créer une ou plusieurs distributions compilées (binaires).

Chacune de ces tâches est couverte dans ce document.

Tous les développeurs de modules n’ont pas accès à une multitude de plateformes, donc on ne peut pas exiger d’eux qu’ils créent une multitude de distributions compilées. On s’attend à ce que certains intermédiaires, appelés packagers, prennent en charge ce besoin. Les packagers vont prendre les sources des distributions publiées par les développeurs de modules, les construire sur on ou plusieurs plateformes, et publier les distributions compilées résultantes. Ainsi, les utilisateurs sur les plateformes les plus populaires vont pouvoir installer la plupart des modules Python de la façon la plus naturelle qui soit pour leur plateforme, sans avoir à exécuter de script ou à compiler du code.

1.2. Un exemple simple

Le script d’installation est habituellement assez simple, même s’il n’y a pas de limite à ce qu’il peut faire (il est écrit en Python, n’est-ce pas ?). Veillez d’ailleurs à ne pas surcharger ce script avec des opérations coûteuses car, contrairement aux scripts de configuration façon Autoconf, le script d’installation peut être amené à être exécuté plusieurs fois au cours de la compilation et de l’installation du module.

Si tout ce que vous voulez est de distribuer un module appelé foo, contenu dans un fichier foo.py, alors votre script d’installation peut se résumer à :

from distutils.core import setup
setup(name='foo',
      version='1.0',
      py_modules=['foo'],
      )

Quelques observations :

  • la plupart des informations que vous fournissez à Distutils sont fournies en tant que qu’arguments nommés à la fonction setup();

  • ces arguments nommés tombent dans deux catégories : métadonnées du paquet (nom, numéro de version) et des informations sur le contenu du paquet paquet (une liste de purs modules Python, dans ce cas) ;

  • les modules sont listés par nom de module, plutôt que par nom de fichier (le cas est similaire pour les paquets et extensions) ;

  • il est recommandé de fournir un minimum de métadonnées, en particulier votre nom, une adresse de courriel et une URL pour le projet (voir section Rédaction du script setup.py pour un exemple).

Pour créer une distribution source pour ce module, il faut créer un script d’installation, setup.py, contenant le code ci-dessus, et exécuter cette commande depuis un terminal :

python setup.py sdist

Pour Windows, ouvrez une invite de commande (Démarrer ‣ Accessoires) et changez la commande en :

setup.py sdist

sdist va créer un fichier d’archive (p. ex. une archive tar sur Unix, un fichier ZIP sous Windows) contenant votre script d’installation setup.py, et votre module foo.py. Le fichier d’archive va être nommé foo-1.0.tar.gz (ou .zip), et va se décompresser dans un répertoire foo-1.0.

If an end-user wishes to install your foo module, all they have to do is download foo-1.0.tar.gz (or .zip), unpack it, and—from the foo-1.0 directory—run

python setup.py install

ce qui va finalement copier foo.py dans le répertoire approprié pour un module tiers dans son installation Python.

Ce simple exemple démontre des concepts fondamentaux de Distutils, Premièrement, les développeurs et installeurs ont la même interface utilisateur basique, p. ex. le script d’installation. La différence est quelle commande Distutils ils utilisent : la commande sdist est quasiment exclusivement pour les développeurs de modules Python, tandis que install est plus souvent pour les installeurs (bien que la plupart des développeurs vont vouloir installer leur code occasionnellement).

Si vous voulez rendre les choses vraiment faciles pour vos utilisateurs, vous pouvez créer on ou plusieurs distributions compilées pour eux. En l’occurrence, si vous tournez sous une machine Windows, et que vous voulez rendre les choses faciles pour les autres utilisateurs Windows, vous pouvez créer un installateur exécutable (le mode de distribution le plus approprié pour cette plateforme) avec la commande bdist_wininst. Par exemple :

python setup.py bdist_wininst

va créer une installeur exécutable, foo-1.0.win32.exe, dans le répertoire courant.

D’autres formats de distributions compilés utiles sont RPM, implémenté par la commande bdist_rpm, Solaris pkgtool (bdist_pkgtool), et HP-UX swinstall (bdist_sdux). Par exemple, la commande suivante va créer un fichier RPM appelé foo-1.0.noarch.rpm:

python setup.py bdist_rpm

(La commande bdist_rpm utilise l’exécutable rpm, cependant cela doit être exécuté sur un système basé sur RPM tel que Red Hat Linux, SuSE Linux, or Mandrake Linux.)

Vous pouvez trouver quelles sont les formats de distribution disponibles à n’importe quel moment en exécutant :

python setup.py bdist --help-formats

1.3. Terminologie Python générale

Si vous lisez ce document, vous avez probablement une bonne idée de ce que sont les modules, extensions, etc. Néanmoins, juste pour être sur que tout le monde opère depuis un point d’entrée commun, nous reprécisons le glossaire suivant des termes Python communs :

module

unité de base de la réutilisabilité en Python : un bloc de code importé par un autre code. Trois types de modules nous concernent ici : les purs modules Python, les modules d’extension, et les packages.

pur module Python

un module écrit en Python et contenu dans un seul fichier .py (et possiblement un fichier .pyc associé). Parfois appelé « pur module. »

module d’extension

un module écrit dans un langage de bas niveau de l’implémentation Python: C/C++ pour Python, Java pour Jython. Typiquement contenu dans un unique fichier pré-compilé chargeable, p. ex. un fichier objet partagé (.so) pour des extensions Python sous Unix, un fichier DLL (étant donné l’extension .pyd) pour les extensions Python sous Windows, ou un fichier de classe Java pour les extensions Jython (notez qu’actuellement, Distutils gère seulement les extensions Python C/C++).

paquet

un module qui contient d’autres modules ; très souvent contenu dans un répertoire du système de fichier et qui se distingue des autres répertoires par la présence d’un fichier __init__.py.

paquet racine

la racine de la hiérarchie de paquets. (Ce n’est pas vraiment un paquet, puisqu’il n’a pas un fichier __init__.py. Mais nous devons bien le nommer.) La grande majorité de la bibliothèque standard est dans le package racine, comme le sont certains petits, des packages tiers autonomes qui n’appartiennent pas à une un module plus grand. Contrairement aux packages réguliers, les modules dans le package racine peuvent être trouvés dans plusieurs répertoires : en effet, tous les répertoires listés sys.path contribuent à faire partie du package racine.

1.4. Terminologie spécifique à Distutils

Les termes suivant s’appliquent plus spécifiquement au domaine de la distribution de modules Python en utilisant les Distutils :

module de distribution

une collection de modules Python distribués ensemble, comme une unique ressource téléchargeable et ayant pour but d’être installé en bloc. Des exemples de modules distribués bien connus sont NumPy, SciPy, Pillow, ou mxBase. (On pourrait les appeler des packages, malgré que le terme soit déjà pris dans le contexte Python : une distribution de module simple pourrait contenir zéro, on ou plusieurs packages Python

distribution de modules purs

une distribution de module qui contient seulement des modules purs et packages Python. Parfois appelée « distribution pure ».

distribution de module non pur

une distribution de module qui contient au moins un module d’extension. Parfois appelée « distribution non-pure ».

distribution racine

le répertoire de plus haut niveau de votre arborescence (ou distribution source) ; le répertoire ou setup.py existe. Généralement setup.py est exécuté depuis ce répertoire.