8. Extension de Distutils

Distutils peut être étendu de multiples façons. La plupart des extensions sont soit des nouvelles commandes soit des remplacements de commandes existantes. De nouvelles commandes pourraient par exemple servir à l'empaquetage pour des plateformes spécifiques tandis que des remplacements peuvent modifier certains aspects des commandes existantes.

La plupart des extensions de distutils sont faites dans le script setup.py. La plupart ajoutent simplement quelques extensions de fichiers qui devraient être copiés dans le paquet en plus des fichiers .py.

La plupart des implémentations des commandes distutils sont des sous-classes de distutils.cmd.Command. Les nouvelles commandes peuvent hériter directement de Command, alors que les remplacements dérivent souvent de Command indirectement, directement sous-classant la commande qu'ils remplacent. Les commandes doivent dériver de la classe Command.

8.1. Intégrer de nouvelles commandes

Il y a différentes façons d’intégrer de nouvelles implémentations de commandes dans distutils. La plus difficile est de faire pression pour inclure une nouvelle fonctionnalité dans distutils même, et d’attendre (et demander) une version de Python l'implémentant. C'est très difficile pour beaucoup de raisons.

La plus commune, et possiblement la plus raisonnable pour la plupart des cas, est d'inclure les nouvelles implémentations dans votre fichier setup.py, et de faire en sorte que la fonction distutils.core.setup() les utilise :

from distutils.command.build_py import build_py as _build_py
from distutils.core import setup

class build_py(_build_py):
    """Specialized Python source builder."""

    # implement whatever needs to be different...

setup(cmdclass={'build_py': build_py},
      ...)

Cette approche est la plus valable si les nouvelles implémentations doivent être utilisées pour utiliser un paquet particulier, vu que toutes les personnes intéressées par le paquet devront avoir ces nouvelles implémentations de commandes.

Depuis Python 2.4, une troisième option est disponible, prévue pour permettre d'ajouter de nouvelles commandes compatibles avec le script existant setup.py sans avoir besoin de modifier l'installation Python. C'est fait pour que les extensions tierces puissent rester compatibles avec d'autres systèmes d'empaquetage, mais les commandes peuvent être utilisées pour tout ce que les commandes de distutils peuvent faire. Une nouvelle option de configuration, command_packages (option shell --command-packages), peut être utilisée pour spécifier des recherches de paquets additionnels pour des modules qui implémentent des commandes. Comme toutes les options distutils, cela peut être spécifié en ligne de commande ou dans un fichier de configuration. Cette option peut être fixée dans la section [global] d'un fichier de configuration, ou avant n'importe quelle commande dans un shell. Si définie dans un fichier de configuration, elle peut être écrasée depuis la ligne de commande. Mettre une chaine de caractères vide en valeur de cette option forcera l'utilisation de la valeur par défaut. Cela ne devrait jamais être fixé dans un fichier de configuration donné avec un paquet.

Cette nouvelle option peut être utilisée pour ajouter n'importe quel nombre de paquet à la liste des paquets recherchés pour les implémentations de commandes ; plusieurs noms de paquets doivent être séparés par des virgules. Quand non spécifié, la recherche est seulement faite dans le paquet distutils.command. Cependant, lorsque setup.py est lancé avec l'option --command-packages distcmds,buildcmds, les paquets distutils.command, distcmds, et buildcmds seront cherchés dans cet ordre. Il est attendu des nouvelles commandes d’être implémentées en modules du même nom que la commande en utilisant des classes partageant le même nom. Comme dans l'exemple shell donné ci-dessus, la commande bdist_openpkg pourrait être implémentée avec la classe distcmds.bdist_openpkg.bdist_openpkg ou buildcmds.bdist_openpkg.bdist_openpkg.

8.2. Ajout de nouveaux types de distribution

Les commandes qui créent des distributions (fichiers dans le dossier dist/) doivent ajouter la paire (command, filename) à self.distribution.dist_files pour que upload puisse publier sur PyPI. Le nom de fichier (filename) dans la paire ne contiens pas de chemin, juste le nom du fichier lui-même. En mode dry-run, les paires doivent toujours être ajoutées pour représenter ce qui aurait été créé.