Python パッケージ化のタスク ランナー#

タスクランナーとは何ですか?#

タスク ランナーは、反復的な開発ワークフローを自動化するツールです。コードのテスト、ドキュメントの構築、パッケージのチェックが必要になるたびに長いコマンド シーケンスを入力する代わりに、これらのタスクを一度定義し、単純なコマンドで実行します。

たとえば、次のように実行するのではなく、

python -m build
twine check dist/*
check-wheel-contents dist/*.whl

タスクを定義して実行できます。

hatch run build:check

最新のタスク ランナーのほとんどには、タスクを迅速かつ簡単に実行できる環境管理機能も含まれています。タスク ランナーを使用すると、ラップトップで実行している場合でも、継続的統合で実行している場合でも、ワークフローが常に一貫して実行されることが保証され、また、コントリビューターがローカル環境で同じワークフローを簡単に再作成できるようになります。

タスクランナーのメリット#

タスク ランナーは、パッケージ開発にいくつかの利点をもたらします。タスク ランナーを使用すると、チームの全員が同じ方法でタスクを実行するため、環境固有の問題や「自分のマシンで動作する」問題が軽減されます。複雑な複数ステップのプロセスが単一のコマンドになるため、投稿者は長いコマンド シーケンスを記憶したり調べたりする必要がありません。

多くのタスク ランナーは、さまざまなワークフロー用に分離された環境も作成し、競合することなく各タスクで適切な依存関係が利用できるようにします。これは、タスクがローカルでも継続的統合でも同じように実行されることを意味し、デバッグが容易になり、ビルドの信頼性が高まります。

2種類のタスクランナー#

Python エコシステムで使用される最も一般的なタスク ランナーは、次の 2 つのカテゴリに分類されます。

環境 + コマンドマネージャー#

これらを使用して、カスタムの分離環境を作成したり、タスクを実行したりできます。

  • Hatch: Hatch は、組み込みのタスク ランナーを含むオールインワンのパッケージ管理ツールです。これは、pyproject.toml ファイル内で宣言型 TOML 構成を使用します。これは、パッケージに関連するすべてのもの (メタデータ、依存関係、タスク) が 1 か所に存在することを意味します。 Hatch は UV とも統合して、環境を迅速に作成します。

  • Nox: Nox は、コードベース (命令型) 構成アプローチを使用する、柔軟な Python ベースのタスク ランナーです。 Python 関数を作成して noxfile.py でタスクを定義すると、複雑なテスト シナリオや条件付きロジックに対して最大限の柔軟性が得られます。これは、Scientific Python エコシステムで特に人気があります。

  • Tox: Tox は、INI または TOML 構成ファイルを使用する成熟した宣言型ツールです。これは、複数の Python バージョンおよび依存関係の組み合わせにわたるテストに特に適しており、Python コミュニティでは長年にわたり標準となっています。

コマンド専用ツール#

これらのツールはコマンドを実行しますが、環境は管理しません。

  • Make: Make は、Makefile を使用する従来のビルド自動化ツールです。これは広く知られており、ほとんどのシステムで利用できるため、Python 固有の機能が必要ない場合の単純なタスクの自動化に適しています。ただし、特に Windows では、クロスプラットフォームの互換性の問題が発生する可能性があります。

  • Just: Just は、シンプルな Make のような構文を使用して Rust で書かれた最新のコマンド ランナーです。これは高速でクロスプラットフォームであり、習得が簡単であるため、環境管理なしで基本的なタスクを実行する必要がある場合の軽量な代替手段として適しています。

一般に、pyOpenSci が提案および使用する 2 つのタスク ランナーは、Nox と Hatch (これもパッケージ管理ツール) です。以下では、すべてのツールの違いについて説明し、ニーズに応じて自分で決定できます。

pyOpenSci が推奨する: Hatch と Nox#

pyOpenSci では、Python パッケージ開発には Hatch を推奨しています。ハッチには、タスクおよび環境システム機能も含まれています。 Hatch を使用すると、Nox などの別のツールをセットアップする必要がなくなります。

ただし、Nox も、特に複雑なテスト、ビルド、またはワークフロー ロジックが必要な場合には優れた選択肢です。

pyOpenSci ドキュメント リポジトリの多くは、ドキュメントの構築やテストなどのワークフローを自動化するために Nox を使用していることがわかります。

ハッチを使用する理由#

Hatch は、メタデータ、依存関係、ビルド構成、およびタスクを pyproject.toml でまとめて管理するのに役立つオールインワン ツールです。 Hatch を使用すると、パッケージに関連するすべてが 1 か所にまとめられます。パッケージ化 (ビルドと公開) とテスト、ドキュメント、フォーマットなどの日常的な開発タスクを組み合わせて、ワークフローの実行と共有を容易にします。 Hatch は UV とも統合されており、非常に高速です。最後に、Hatch は最新のパッケージ化慣行 (PEP 621 など) に従っているため、プロジェクトはコミュニティ標準に準拠した状態を維持できます。

Nox を使用する理由#

Python ベースの構成により Nox に最大限の柔軟性が与えられ、複雑なロジックや条件を直接簡単に表現できるようになります。セッションは Python で記述されているため、明示的であり、検査とデバッグが簡単です。 Nox は、一部のパッケージに必要な複雑なテストとビルドのシナリオを処理するのに特に強力です。

宣言型構成と命令型構成#

これらのツールの重要な違いは、その構成方法です。

ハッチングは 宣言型ツール です。これは、必要な「内容」を指定する構成ファイルを使用することを意味します。以下の例を参照してください。

# pyproject.toml (Hatch)
[tool.hatch.envs.test]
dependencies = ["pytest", "pytest-cov"]

[tool.hatch.envs.test.scripts]
run = "pytest {args:tests}"

Nox は、命令的 アプローチを使用してワークフローを定義します。 Nox では、タスクの実行方法を定義する Python コードを作成します。 Nox 関数の例 (別の noxfile.py ファイルに存在します) を以下に示します。

# noxfile.py (Nox)
@nox.session
def test(session):
    session.install("pytest", "pytest-cov")
    session.run("pytest", *session.posargs)

トレードオフ: 宣言型と命令型#

  • 宣言型 (Hatch、Tox): 構文が単純になり、読みやすく、保守しやすくなります。複雑なロジックの場合は柔軟性が若干劣る可能性があります (これはユーザーに依存します)。

  • 命令型 (Nox): 複雑なロジックや条件を簡単に含めることができます。 Pythonを使っているので、より馴染みがあるかもしれません!

どちらのアプローチが本質的に優れているというわけではなく、ニーズや好みによって異なります。複雑なテストシナリオを伴うプロジェクトは Nox の柔軟性の恩恵を受ける可能性がありますが、シンプルで標準化されたワークフローを必要とするプロジェクトは宣言型構成の明確さを好む場合があります。

にあるコア タスク ランナー ツールの概要#

Python エコシステム

比較表#

以下に、各ツールに関連する機能の比較を示します。次に、より詳しく知りたい場合に備えて、各ツールについてもう少し詳しく説明します。

特徴

ハッチ

ノックス

トックス

作る

ただ

構成

pyproject.toml

noxfile.py

tox.ini

メイクファイル

ジャストファイル

構成スタイル

宣言的

命令的

宣言的

宣言的

宣言的

言語

TOML

パイソン

INI/TOML

構文を作成する

構文だけ

Python 固有

はい

はい

はい

いいえ

いいえ

環境管理

はい

はい

はい

いいえ

いいえ

マトリックス テスト

はい

はい

はい

いいえ

いいえ

パッケージの統合

はい

いいえ

いいえ

いいえ

いいえ

クロスプラットフォーム

はい

はい

はい

限定

はい

こんな用途に最適

パッケージ開発を完了する

複雑なテストワークフローとその他のビルド

レガシープロジェクト、標準テスト

単純なタスク

簡単なコマンド

ハッチ#

Hatch は、最新のオールインワン パッケージ化およびタスク自動化ツールで、ビルドと公開からテストの実行とコードのフォーマットまですべてを処理することで、Python パッケージ開発を簡素化します。ハッチは、[このガイドブックにあるパッケージング チュートリアルで]使用するものです(packaging-101)。

ハッチが好きな理由#

Hatch が際立っているのは、パッケージ化とタスクの実行の両方を単一のツールで処理できるためです。複数のツールを使いこなす代わりに、「pyproject.toml」ファイルですべてを設定します。追加の設定ファイルは必要ありません。 Hatch は、さまざまなタスク (ドキュメントのテストや構築など) 用に分離された環境を作成し、UV と統合して非常に高速な環境セットアップを実現します。読みやすく保守しやすい宣言的でクリーンな構文を使用しており、マトリックス テストをサポートしているため、複数の Python バージョンにわたってパッケージを簡単にテストできます。

ハッチを使用する場合#

Hatch は、完全なパッケージ開発ワークフローに最適です。これは、Python バージョン間でのテスト、ドキュメントの構築、コード フォーマッタとリンターの実行、パッケージの構築と PyPI への公開に使用できます。現在の Python パッケージ標準 (PEP 621 など) に準拠した最新のオールインワン ソリューションが必要な場合、Hatch は優れた選択肢です。

構成例#

以下は、Hatch でテスト環境をセットアップする方法の例です。この構成では、pytest と pytest-cov がインストールされた「test」環境を作成し、テストを実行する「run」スクリプトを定義し、Python 3.10、3.11、および 3.12 でテストを実行するためのマトリックス テストを設定します。

# pyproject.toml

# This is a hatch environment (venv) called "test" that contains two dependencies
[tool.hatch.envs.test]
dependencies = ["pytest", "pytest-cov"]

# This is a script that hatch can run in the environment defined above.
[tool.hatch.envs.test.scripts]
run = "pytest {args:tests}"

# This is how you setup a matrix where hatch will create environments for each python version and run the test scripts in each environment. It will use UV to install python for each environment!
[[tool.hatch.envs.test.matrix]]
python = ["3.10", "3.11", "3.12"]

以下を使用してターミナルで上記を実行します。

ハッチ実行テスト:実行

詳細: Hatch ドキュメント

ノックス#

Nox は、複数の環境にわたるテストに焦点を当てた Python ベースの自動化ツールキットです。コードベースの (命令型) 構成アプローチを使用しており、複雑なテスト ワークフローに最大限の柔軟性をもたらします。

Nox が好きな理由#

Nox が際立っているのは、Python コードを使用してタスクを定義しているためです。つまり、複雑なロジックや条件を自動化ワークフローに直接組み込むことができます。セッションは Python で記述されているため、明示的であり、検査が簡単で、デバッグも簡単です。 Nox は、一部のパッケージで必要とされる複雑なテストおよびビルド シナリオの処理に特に強力であり、Scientific Python エコシステムで特に人気があります。多くの pyOpenSci ドキュメント リポジトリが Nox を使用してドキュメントの構築やテストなどのワークフローを自動化していることがわかります。

Nox を使用する場合#

Nox は、条件付きロジックを使用した複雑なテスト シナリオが必要な場合、または宣言形式よりも Python ベースの構成を好む場合に最適です。 Python のバージョン間でのテストや、複数のテスト環境の管理に最適です。パッケージ化が個別に処理され、タスクの自動化に最大限の柔軟性が必要な場合は、Nox が最適な選択肢です。

構成例#

以下は、複数の Python バージョンにわたってテストを実行する Nox セッションの例です。 @nox.session デコレーターはセッション (タスクと同様) を定義し、テストに使用する Python バージョンを指定します。 Nox はバージョンごとに隔離された環境を作成し、テストを実行します。

# noxfile.py
@nox.session(python=["3.10", "3.11", "3.12"])
def tests(session):
    # Install test dependencies
    session.install("pytest")
    # Run the tests
    session.run("pytest")

以下を使用してターミナルで上記を実行します。

「nox -s テスト」

詳細: Nox ドキュメント

トックス#

Tox は、複数の環境でテストするための成熟した自動化ツールです。これは宣言型構成を使用しており、Python コミュニティでは長年にわたり標準となっています。

なぜ人々はToxを使用するのか#

Tox は成熟していて安定しており、Python エコシステム内で長い歴史があります。宣言型構成 (最近 TOML サポートが追加されましたが、伝統的に INI 形式) を使用しており、Python のバージョンと依存関係セットにわたるテストに特に適しています。 Tox は CI/CD システムとうまく統合され、堅牢なプラグイン エコシステムを備えているため、多くのプロジェクトで Tox が使用されています。

トックスをいつ使用するか#

Tox は、既に使用しているレガシー プロジェクトを維持している場合、または保存したい既存の tox.ini 設定がある場合に最適です。特定の Tox プラグインが必要な場合や、パッケージ化ツールとは別の宣言型構成を希望する場合にも、これは良い選択です。ただし、Tox は Hatch などの最新の代替手段よりも遅い可能性があることに注意してください。

構成例#

以下は、複数の Python バージョンにわたってテストを実行する Tox 構成の例です。 「envlist」はテストする Python バージョンを指定し、「testenv」セクションは何をインストールして実行するかを定義します。

# tox.ini
[tox]
envlist = py310,py311,py312

[testenv]
deps = pytest
commands = pytest tests/

以下を使用してターミナルで上記を実行します。

tox (すべての環境を実行) または tox -e py310 (特定の環境を実行)

さらに詳しく: Tox ドキュメント

作る#

Make は、Makefile を使用する従来のビルド自動化ツールです。 1970 年代から存在し、多くのプログラミング言語で広く使用されています。

Make を使用する理由#

Make は広く知られており、ほとんどのシステムで利用できるため、多くの開発者にとって馴染みのある選択肢となっています。基本的なタスク用の単純な構文を備えており、非常に高速に実行されます。これは Python 固有ではないため、同じプロジェクト内の異なる言語間でタスクを調整するために使用できます。

Make を使用する場合#

Make は、Python 固有の機能や環境管理が必要ない場合の単純なタスクの自動化に最適です。高速で誰でも利用できるものが必要な場合には、これは優れた軽量オプションです。ただし、Make には、特に Windows 上でクロスプラットフォーム互換性の問題が発生する可能性があり、Python 環境の管理を個別に処理する必要があることに注意してください。

構成例#

以下は、ドキュメントのテストと構築のためのタスクを含む単純な Makefile の例です。

test:
    pytest tests/

docs:
    sphinx-build docs docs/_build

以下を使用してターミナルで上記を実行します。

make test または make docs

ただ#

Just は、Rust で書かれた最新のコマンド ランナーで、Make のよりシンプルでユーザーフレンドリーな代替手段を提供します。

Just を使用する理由#

シンプルで Make に似た構文を持ちますが、エラー メッセージが改善され、動作がより直感的になります。これは高速で、真にクロスプラットフォームで (Make とは異なり)、習得が簡単です。このツールは Rust で書かれているため、非常にパフォーマンスが高く、Make が数十年にわたって蓄積してきた癖や注意点の多くが回避されています。

「ジャスト」を使用する場合#

Just は、単純なタスク用の軽量のコマンド ランナーが必要で、Python 固有の機能や環境管理を必要としない場合に最適です。 Make よりも高速で最新の、より優れたクロスプラットフォーム サポートが必要な場合は、これが最適な選択です。ただし、Just は個別のインストールが必要であり、Hatch や Nox などのツールと比べて Python パッケージ化エコシステムとの統合が少ないことに注意してください。

構成例#

以下は、ドキュメントのテストと構築のためのタスクを含む justfile の例です。

# justfile
test:
    pytest tests/

docs:
    sphinx-build docs docs/_build

以下を使用してターミナルで上記を実行します。

「テストだけ」または「ドキュメントだけ」

詳細: Just ドキュメント

適切なタスク ランナーの選択#

次の場合はハッチングを選択してください:

  • Python パッケージを構築しています

  • オールインワンツールが欲しい

  • pyproject.toml での設定を希望する場合

  • 迅速な環境管理が必要な場合

  • 宣言型構成を好む場合

次の場合は Nox を選択してください:

  • 条件付きロジックを使用した複雑なテスト シナリオが必要な場合

  • Python ベースの命令型構成を好む場合

  • あなたは Scientific Python エコシステムで働いています

  • 梱包は別途対応させていただきます

  • 最大限の柔軟性が必要な場合

次の場合は Tox を選択してください:

  • すでに使用しているレガシー プロジェクトを維持している

  • 既存の tox.ini 設定がある

  • 特定の有害なプラグインが必要です

  • パッケージ化とは別に宣言的な構成を好む場合

Make または Just if を選択してください:

  • 軽量のコマンドランナーが必要です

  • Python 固有のワークフローを実行していない

  • シンプルで速いものが欲しい

  • 環境管理は必要ありません

次のステップ#