パッケージングとプロジェクトの配布#
- ページステイタス:
期限切れのもの
- 最終査読日:
2023-12-14
この節では、 setuptools
を使ったPythonパッケージの設定・パッケージング・配布方法について、 :doc:`/tutorials/packaging-projects`_ の入門的なチュートリアルでは触れていないような追加的な詳細を説明します。あなたが既に パッケージをインストールする ページの内容については慣れ親しんでいるものと仮定して進めます。
この節は、Pythonプロジェクトの開発についての全体的なベストプラクティスを説明しているわけではありません。例えば、バージョン管理や文書化、あるいは試験について、手引きとなったりツールを推奨するようなことはありません。
より詳しい参考文献としては、Setuptools の説明文書の中の パッケージのビルドと配布 を挙げておきますが、推奨事項のいくつかはもはや古くなっているかもしれません。喰い違いがあった場合には、Python パッケージングユーザガイドの推奨事項を優先してください。
パッケージングと配布に対する要求事項#
最初に、あなたが既に パッケージをインストールする際の要求事項 を満たしていることを確実にしてください。
"twine"をインストールする [1]:
python3 -m pip install twine
py -m pip install twine
あなたのプロジェクトを設定する#
最初に必要なファイル群#
setup.py#
最重要のファイルは、あなたのプロジェクトのディレクトリの一番上(ルート)にある setup.py
です。PyPA サンプルプロジェクト の setup.py に具体例があります。
setup.py
はふたつの主要な機能を提供します。
まず、あなたのプロジェクトをさまざまな角度から設定するためのファイルです。
setup.py
の主要な機能は、グローバルなsetup()
関数を含んでいることです。この関数にキーワード引数を渡すことで、あなたのプロジェクトの特定の細部を定義することができます。適切な引数のほとんどについて 次節 で説明します。それは、パッケージングする上での作業項目に関連したさまざまなコマンドを走らせるためのコマンドラインインタフェイスです。使用可能なコマンドを一覧するには、
python setup.py --help-commands
を実行してください。
setup.cfg#
setup.cfg
は setup.py
のコマンド群に対するオプションの既定値を含む初期化ファイルです。 PyPA サンプルプロジェクト の中の setup.cfg に使用例が出ています。
README.rstとREADME.md#
すべてのプロジェクトは、プロジェクトのゴールを記したreadmeファイルを備えるべきです。一番良くあるフォーマットは拡張子が "rst" の reStructuredText ですが、これは(訳註、必須の)要求事項というわけではありません。他にも複数の種類の マークダウン フォーマットがサポートされています(setup()
の long_description_content_type 引数を見てください)。
PyPA sample project の中の README.md に例が出ています。
注釈
setuptools`の0.6.27およびそれ以降のバージョンを使っているプロジェクトでは、標準のreadmeファイル(:file:`README.rst、 README.txt
、または README
)がデフォルトでソースコード配布物に含まれるようになっています。標準ライブラリの distutils では、Python 3.7からこの動作を採用しました。さらに、Setuptools の36.4.0およびそれ以降のバージョンでは、もし見つかれば README.md
を含めるようになっています。もしあなたがsetuptoolsを使っているのであれば、あなたはreadmeファイルを MANIFEST.in
に明記する必要はありません。そうでないなら、明示的に書いてください。
MANIFEST.in#
自動的に追加されるファイル以外のファイルをソースコード配布物に追加したい場合には、 MANIFEST.in
が必要になります。 どんなファイルがデフォルトで自動的に追加されるのかも含めて、 MANIFEST.in
の書き方の詳細については「 MANIFEST.in の使い方」を見てください。
しかしながら、あなたは必ずしも MANIFEST.in
を使わなくても構いません。一つの例として`PyPA サンプルプロジェクト <https://github.com/pypa/sampleproject>`_ では、必要なファイルがすべて 43.0.0およびこれ以降の:ref:`setuptools`に含まれているので、マニフェストファイルを削除しています。
注釈
MANIFEST.in
は、wheelなどのバイナリ配布物には影響を与えません。
LICENSE.txt#
各パッケージは、配布の条件を指定するライセンスファイルを含んでいるべきです。多くの司法管轄区域(訳註、大雑把にいうと「多くの国」)では、明示的なライセンス条項がないと、著作権保持者でなければ誰も適法にパッケージを使用したり配布したりすることができません。どのライセンスを選択すればよいか分からない場合には、GitHubの「オープンソースライセンスを選ぶには」 などのリソースを見ることも、弁護士に相談することもできます。
PyPAサンプルプロジェクト の LICENSE.txt に例がでています。
<あなたのパッケージ>#
必ずそうしなければならないというわけではありませんが、あなたのプロジェクトと同じか非常に近い 名前 の単一のプロジェクトをPythonのモジュールやパッケージのトップレベルに配置するということが共通の慣習になっています。
PyPAサンプルプロジェクト に含まれる サンプル パッケージに例が出ています。
setup() の引数#
上述の通り、setup.py
の第一の機能は、グローバルスコープの setup()
関数を含むことです。この関数に与えるキーワード引数は、あなたのプロジェクトの特定の細部がどのように定義されているかを示すものです。
いくつかについては、情報がどこか他の場所に移されるまでの一時的な説明が以下にあります。すべてを列挙したものは setuptools の説明文書 で見つかるでしょう。
ほとんどのソースコード断片(スニペット)は、PyPA サンプルプロジェクト の中の setup.py から取られたものです。
あなたのユーザへ互換性情報を伝える方法としてバージョン番号を使うやり方については、 バージョンをつける規則を選択するには をご覧ください。
packages
#
packages=find_packages(include=['sample', 'sample.*']),
packages
には、あなたのプロジェクトにある パッケージ を子パッケージや孫パッケージなども含めてすべて列挙してください。パッケージは手動で列挙することもできますが、 setuptools.find_packages()
を使えば自動で列挙することができます。 include
キーワード引数を使うと、ここに与えられた特定のパッケージだけを探索することができます。 exclude
キーワード引数を使うと、公開したりインストールしたりする意図のないパッケージを除外することができます。
py_modules
#
py_modules=["six"],
あなたのプロジェクトに、プロジェクトの一部ではない単一ファイルのPythonモジュールがあるなら、 Setuptools に知らせるために、そのようなモジュールの(拡張子``.py``を削除した)名前を py_modules
に列挙してください。
install_requires
#
install_requires=['peppercorn'],
install_requires
は、プロジェクトが動作するために最低限必要な依存関係を指定するのに使われます。プロジェクトが pip でインストールされる場合には、この指定を見て依存関係(訳註、にある他パッケージ)をインストールするために用いられます。
さらなる install_requires
の使い方については install_requires対Requirementsファイル を参照してください。
package_data
#
package_data={
'sample': ['package_data.dat'],
},
追加のファイルを パッケージ にインストールする必要がある、というのはよくあることです。このようなファイルは、しばしば、そのパッケージの実装に深く関係していたり、パッケージを利用するプログラマの利益になるような説明を含んだテキストファイルであったりします。このようなファイルは「パッケージデータ」と呼ばれます。
この引数に渡す値は、パッケージ名から、そのパッケージ内にコピーされるべきファイルの相対パス名を列挙したもののマッピングになっていなければなりません。パス名はパッケージを含むディレクトリからの相対パスとして解釈されます。
詳しくは、 setuptools説明文書 の中の データファイルを追加するには を見てください。
data_files
#
data_files=[('my_data', ['data/data_file'])],
パッケージデータ を設定すればほとんどの需要に応えられますが、あなたの パッケージ の 外側 にデータファイルを置きたいこともあるでしょう。 data_files
ディレクティブでそれができます。大抵は、Pythonのパッケージを認識しないような他のプログラムから利用するファイルをインストールする必要がある時に、これが役に立つでしょう。
設定値の中の (ディレクトリ, ファイル)
の組は、それぞれインストール先のディレクトリとそこにインストールされるべきファイル(群)を指定しています。 ディレクトリ <directory>
は相対パスでなければならず (これは将来変更されるかもしれません。 wheel Issue #92 を見てください)、インストール先プレフィクス(デフォルトではPythonの sys.prefix
、ないし、ユーザインストールでは site.USER_BASE
)に対する相対パスとして解釈されます。 files
内のファイル名は、プロジェクトのソースコード配布物の最上位にある setup.py
スクリプトに対する相対パスとして解釈されます。
さらに詳しくは、 追加的なファイルをインストールするには の中のdistutilsの節を見てください。
注釈
パッケージをeggとしてインストールする時には、 data_files
はサポートされていません。だから、もしあなたのプロジェクトで Setuptools を使っているならば pip
でインストールしなければなりません。あるいは、 --old-and-unmanageable
オプション付きの python setup.py
を使わなければなりません。
scripts
#
setup()
はあらかじめ作成されたスクリプトをインストールするために scripts キーワードをサポートしていますが、異機種間の互換性を取るためのアプローチとして推奨されるのは 実行可能なスクリプトを作成する エントリーポイント(後述)を使うことです。
バージョン体系を選択する#
よくあるバージョンを指定する枠組みにどんなものがあるかや、その中からひとつの枠組みを選択する方法については、 バージョニング を見てください。
開発モードで作業する#
あなたがまだ作業している途中なら、プロジェクトを「編集可能」または「開発」モードでインストールすることができます。編集可能な状態でインストールされると、再インストールしなくてもプロジェクトをその場で編集することができます: 編集可能状態でインストールされたプロジェクトのPythonソースコードに変更を加えると、次にインタープリターのプロセスが開始された時に反映されます。
Pythonのパッケージを「編集可能」/「開発」モードでインストールするには、そのプロジェクトのルートディレクトリへ移動して、次のコマンドを走らせてください:
python3 -m pip install -e .
pip のコマンドラインオプションの -e
は --editable
の省略形で、 .
は現在作業をしているディレクトリのことですので、まとめると「現在のディレクトリ(つまりあなたのプロジェクト)に編集可能モードでインストールせよ」ということになります。また、このコマンドによって install_requires
に宣言された依存先のパッケージや console_scripts
に書かれたスクリプトもインストールされます。
依存先のプロジェクトも同様に編集可能モードでインストールしたい時があるかもしれません。例えば、あなたのプロジェクトが "foo" と "bar" というパッケージを要求していて、 "bar" についてはVCS (バージョンコントロールシステム) から編集可能モードでインストールしたい場合には、requirements ファイルを次のように構成すれば良いでしょう:
-e .
-e bar @ git+https://somerepo/bar.git
最初の行ではあなたのプロジェクトとその依存先をインストールするように指示しています。2行目で、 "bar" についてPyPIではなくVCSから充当するようにと依存関係を上書きしています。
そうではなくて、 "bar" をローカルディレクトリから編集可能モードでインストールしたい場合には、 requirements ファイルの先頭にローカルのディレクトリパスを置いて次のようになるでしょう:
-e /path/to/project/bar
-e .
さもなければ requirements ファイルに書かれた順にインストールされてしまうので、依存先のパッケージが PyPI から充当されてしまいます。 requirements ファイルについてさらに詳しく知りたい場合は、 pipの解説文書の Requirements ファイル の節を見てください。VCSからのインストールについては、同書の VCSサポート の節を見てください。
最後に、もし依存先パッケージは何もインストールしたくないのであれば、このようにします:
python3 -m pip install -e . --no-deps
さらに詳しいことを知りたい場合は、 Setuptools 文書の 開発モード の 節を見てください。
プロジェクトをパッケージングする#
あなたのプロジェクトを PyPI のような パッケージインデックス からインストールできるようにするには、 配布物 (:term:`パッケージ <Distribution Package>`の名前でも知られる) を作成しなければならないでしょう。
あなたのプロジェクトでwheelsやsdistsをビルドする前に、 build
パッケージをインストールする必要があります。
python3 -m pip install build
py -m pip install build
ソースコード配布物#
少なくとも、 ソースコード配布物 を作成するべきです:
python3 -m build --sdist
py -m build --sdist
ソースコード配布物はビルドされていない (すなわち、 ビルド済み配布物 ではない) ので、pip でインストールする際にビルドする段階が必要になります。配布物が純Python (つまり (訳注、多言語で書かれた) 拡張を含まない) であったとしても、 setup.py
や setup.cfg
からインストール用メタデータを取り出してビルドする段階を必要とするのです。
Wheels#
あなたのプロジェクトでは、wheelも作成するべきです。wheel は、インストールするのにビルド処理を行う必要がない ビルド済み配布物 です。wheelを使えば、ソースコード配布物からのインストールに比べてエンドユーザにとって相当素早くインストールすることができます。
あなたのプロジェクトが純Pythonなら、きっとあなたは:ref:`"純PythonのWheel" (後述) <Pure Python Wheels>`を作成することになるでしょう。
もしあなたのプロジェクトにコンパイル済の拡張が含まれているなら、 *プラットフォーム Wheel* (後述) を作成することになるでしょう。
注釈
あなたのプロジェクトが Python 2をさぽーとしていて、かつ、C言語拡張を含むのであれば、次のものをあなたの setup.cfg
ファイルに追加して ユニバーサル Wheel と呼ばれるものを作成するべきです:
[bdist_wheel]
universal=1
あなたのプロジェクトにC言語拡張がなく、かつ、Python 2 および3をサポートしている場合に限って、この設定を使ってください。
純Python Wheels#
純Python Wheels は、コンパイル済拡張を含んでおらず、従って単独のPython wheelを要求するだけです。
wheelをビルドするには:
python3 -m build --wheel
py -m build --wheel
wheel
パッケージは、ソースコードが純Pythonであることを検出して、Python 3 へのインストールであればどこでも使えるのでそのように名付けられたwheelをビルドします。wheelファイルの名称について詳しいことは PEP 425 を見てください。
--wheel
か --sdist
を付けずに build
を実行すると、両方のファイルが作成されます; 複数のwheelファイルにしたくないときにはこれが便利です。
プラットフォームWheels#
プラットフォームWheels は、LinuxやmacOSあるいはWindowsのような特定のプラットフォーム向けのwheelで、大抵の場合は(訳注、特定のプラットフォーム向けにコンパイルされた)コンパイル済み拡張を含むためです。
wheelをビルドするには:
python3 -m build --wheel
py -m build --wheel
wheel
パッケージは、ソースコードが純Pythonで書かれていないと判断すると、ビルドされたプラットフォーム上でのみ利用可能であるように命名されたwheelを作成します。wheelファイルの命名規則については、 PEP 425 を見てください。
注釈
現在、 PyPI は、Windows向けとmacOS向け、そして複数のLinuxディストリビューションに対応した manylinux*
のABI向けのプラットフォームWheelsをアップロードすることに対応しています。
プロジェクトをPyPIにアップロードする#
配布物を作成するコマンドを走らせると、あなたのプロジェクトのルートディレクトリに dist/
という新しいディレクトリが作成されます。ここに配布物のファイル(群)が置かれます。
注釈
これらのファイルは、配布物作成のコマンドを走らせたときにだけ作成されます。ということは、プロジェクトのソースコードや setup.py
の中の設定を変更したときにはいつでも、PyPIへ送る前に配布物のファイルを再作成する必要があるということです。
注釈
PyPIの主リポジトリでリリースをする前に、半定期的に消去される PyPI 試験サイト で練習する方が良いかもしれません。どのように設定すれば試験サイトを使えるかについては、 TestPyPI を使う を見てください。
警告
他のリソースでは、 python setup.py register
と python setup.py upload
に遭遇するかもしれません。これらのメソッドはパッケージを登録ないしアップロードするものですが、 いくつかのバージョンのPythonで使うと平文のHTTPか検証しないHTTPSを用いるのであなたのユーザ名とパスワードが 通信経路上で横取りされる恐れがあって 強く非推奨 の状態になっています。
Tip
PyPIで使っている reStructuredText パーサは Sphinx ではありません! その上、全ユーザの安全を確保するためにある種の URL やディレクティブ(例えば .. raw::
ディレクティブ)は禁止されていたり削除されたりしています。あなたの配布物をアップロードしてみる 前に setup.py
の中の brief/long description が文法的に妥当かどうかを確かめるべきです。あなたのパッケージのファイル群に対して twine check を走らせれば、それを確かめることができます。
twine check dist/*
アカウントを作成する#
まず、 PyPI のユーザアカウントが必要です。 PyPIウェブサイトにあるフォームを使えば アカウントを作成することができます。
次に PyPI の API トークン を作成して、プロジェクトを安全にアップロードできるようにしましょう。
https://pypi.org/manage/account/#api-tokens and create へ行って、新しい API トークン を作成してください; これから新しいプロジェクトを作成するわけですから、スコープを特定のプロジェクトに限定しないようにしてください。
トークンをコピーして保存するまではページを閉じないでください -- トークンは二度と表示されることがありません。
注釈
$HOME/.pypirc
ファイルを作っておくことで、アップロードするたびにトークンをコピー・ペーストする手間を省くことができます。
[pypi]
username = __token__
password = <the token value, including the `pypi-` prefix>
このファイルにはトークンが平文で保存されていることに注意してください。
.pypirc
についてさらに詳しく知りたい場合は specification を見てください。
配布物をアップロードする#
アカウントが入手できれば、 twine を使ってあなたの配布物を PyPI へアップロードすることができます。
リリースをアップロードする手続きは、そのプロジェクトがPyPIに既に存在していても存在していなくても同じです - もしまだ存在していなければ、最初にリリースがアップロードされたときに自動的に作成されます。
2回目やそれ以降のリリースで PyPI が要求するのは、新しいリリースのバージョン番号が先行するすべてのリリースとは異なるものであることだけです。
twine upload dist/*
sampleproject
のところをアップロードしているプロジェクトの名前に置き換えるとして、 https://pypi.org/project/<sampleproject>
に誘導されれば、あなたのパッケージのアップロードは成功です。あなたのプロジェクトがサイト上に表示されるまでには1,2分の時間がかかるかもしれません。