# 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.

Beginning with Python 2.4, a third option is available, intended to allow new commands to be added which can support existing `setup.py` scripts without requiring modifications to the Python installation. This is expected to allow third-party extensions to provide support for additional packaging systems, but the commands can be used for anything distutils commands can be used for. A new configuration option, `command_packages` (command-line option `--command-packages`), can be used to specify additional packages to be searched for modules implementing commands. Like all distutils options, this can be specified on the command line or in a configuration file. This option can only be set in the `[global]` section of a configuration file, or before any commands on the command line. If set in a configuration file, it can be overridden from the command line; setting it to an empty string on the command line causes the default to be used. This should never be set in a configuration file provided with a package.

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éé.