# 7. Distutilsの拡張

注釈

このドキュメントは、 https://setuptools.readthedocs.io/en/latest/setuptools.html にある `setuptools` のドキュメントが現時点でここにある関連情報を全て網羅するまで、単独でここに載せておかれます。

Distutilsは様々な方法で拡張できます。ほとんどの拡張は新規のコマンドという形をとるか、既存のコマンドを置換します。例えば、新しいコマンドはプラットフォーム特有の新しいパッケージ形式をサポートするために書かれているかもしませんし、既存のコマンドを置換するものは既存コマンドでのパッケージ処理の詳細を変更するでしょう。

ほとんどのdistutilsの拡張は、既存コマンドの動作を修正したい `setup.py` スクリプト中で行われます。その多くは、パッケージ中にコピーすべきファイルとして、 `.py` ファイル以外のいくつかのファイル拡張子を単に追加するものです。

ほとんどのdistutilsのコマンド実装は `distutils.cmd` の `distutils.cmd.Command` クラスのサブクラスとして実装されています。新しいコマンドは `Command` を直接継承し、置換するコマンドでは置換対象のコマンドのサブクラスにすることで `Command` を間接的に継承します。コマンドは `Command` から派生したものである必要があります。

## 7.1. 新しいコマンドの統合

新しいコマンド実装をdistutilsに統合するにはいくつかの方法があります。一番難しい方法は新機能をdistutils本体に取り込むように働きかけ、そのサポートを提供するPythonのバージョンが出ることを待つ(そして要求する)ことです。これは様々な理由で本当に難しいことです。

もっとも一般的な、そしておそらくほとんどの場合にもっとも妥当な方法は、新しい実装をあなたの `setup.py` スクリプトに取り込み、 `distutils.core.setup()` 関数でそれらを使うようにすることです:

    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},
          ...)

このアプローチは、新実装をある特定のパッケージで利用したい時、そのパッケージに興味をもつ人全員がコマンドの新実装を必要とする時にもっとも価値があります。

Python 2.4から、インストールされたPythonを変更せずに、既存の `setup.py` スクリプトをサポートするための3つめの選択肢が利用できるようになりました。これは追加のパッケージングシステムのサポートを追加するサードパーティ拡張を提供することを想定していますが、これらのコマンドはdistutilsが利用されている何にでも利用可能です。新しい設定オプション `command_packages` (コマンドラインオプション `--command-packages`) は、コマンド実装モジュールを検索する追加のパッケージを指定するために利用できます。 distutilsの全てのオプションと同様に、このオプションもコマンドラインまたは設定ファイルで指定できます。このオプションは設定ファイル中では `[global]` セクションか、コマンドラインのコマンドより前でだけ設定できます。設定ファイル中で指定する場合、コマンドラインで上書きすることができます。空文字列を指定するとデフォルト値が使われます。これはパッケージと一緒に提供する設定ファイルでは指定しないでください。

この新オプションによってコマンド実装を探すためのパッケージをいくつでも追加することができます。複数のパッケージ名はコンマで区切って指定します。指定がなければ、検索は `distutils.command` パッケージのみで行われます。ただし `setup.py` がオプション `--command-packages distcmds,buildcmds` で実行されている場合には、パッケージは `distutils.command` 、 `distcmds` 、そして `buildcmds` を、この順番で検索します。新コマンドはコマンドと同じ名前のモジュールに、コマンドと同じ名前のクラスで実装されていると想定しています。上のコマドラインオプションの例では、コマンド bdist_openpkg は、 `distcmds.bdist_openpkg.bdist_openpkg` か、 `buildcmds.bdist_openpkg.bdist_openpkg` で実装されるかもしれません。

## 7.2. 配布物の種類を追加する

配布物 (`dist/` ディレクトリの中のファイル) を作成するコマンドは、 upload がその配布物をPyPIにアップロードできるように、 `(command, filename)` のペアを `self.distribution.dist_files` に追加する必要があります。ペア中の filename はパスに関する情報を持たず、単にファイル名だけを持ちます。 dry-run モードでも、何が作成されたかを示すために、同じペアが必要になります。