福田
はじめに
Pythonで新しいプロジェクトを作る時にどのように始めますか? 新しいライブラリを作りたい、仕事で新しいPythonのプロジェクトが始まる、といったような場面で、プロジェクトのディレクトリ構成やフォーマッターやタスクランナーなどをどのように管理するか悩んだことはありませんか?
Python以外の言語、たとえばRustではCargo、JavaScriptではnpm、RubyではBundlerなど、言語ごとにプロジェクトの管理を支援するツールがあります。PythonにもPythonプロジェクトを管理するさまざまなツールがありますが、今回はその中の1つ
Hatchとは
Hatchは、Pythonプロジェクトの管理を支援するコマンドラインツールです。デフォルトでディレクトリ構成が決められており、バージョン管理もでき、タスクを登録して実行することもできます。
比較対象になるツールとして、Poetryやpdmがあります。どのツールでも同じようなことができますが、それらと異なるHatchの特徴として大きく2点が挙げられます。
- Pythonインタープリターを管理できる
- 既定の設定が充実している
- ビルドやテスト、フォーマッターなどが既定の状態で利用できる
Python環境をpyenvや公式のインストーラーなどで管理する必要がなく、Hatchだけで完結できます。公式サイトの
さらに、Hatchの内部では、フォーマットや静的コード解析に過去に本連載でも紹介したRuffを採用しており、またuvも設定で利用可能なため、高速である点も特徴のひとつです。
Hatchの設定は、pyproject.
プロジェクトのメタデータは標準に基づいており、ビルド システムはPEP 517 / PEP 660と互換性があるため、他のツールからの移行も簡単です。
また、Hatchはpypaで管理されているリポジトリです。開発も非常に活発で、記事執筆時点
Hatchにできること
Hatchにできることは以下の通りです。
- プロジェクトのディレクトリ構成やpyproject.
tomlファイルを自動作成できる - コードフォーマットや静的解析、テストを他のツールをインストールせずに実行できる
- タスクランナー機能でプロジェクトに必要なタスクを登録でき、自動化しやすい
- プロジェクトのビルド、PyPIへのデプロイが大きな設定変更なしでできる
- プロジェクトのバージョンを管理できる
- Pythonインタープリターを管理できる
Hatchを使ってみよう
Hatchの主な使い方を紹介します。
また実際にHatchを利用して、小さなサンプルプロジェクトを作成してみました。Hatchでプロジェクトを作成した直後のブランチと、最低限の変更をしたブランチがあります。本記事と合わせて、ブランチの差分をご参考ください。
- サンプルプロジェクト: jrfk/
pdfysvg - 初期状態のブランチ: jrfk/
pdfysvg at bootstrap-by-hatch - 変更後のブランチ: jrfk/
pdfysvg at feature/ bootstrap-enhancements
Hatchのインストール
HatchはLinux、macOS、Windowsで動作し、インストール方法にはさまざまな方法があります。今回はMacでグローバルに利用できるように公式のインストーラーを利用しました。
$ curl -Lo hatch-universal.pkg https://github.com/pypa/hatch/releases/latest/download/hatch-universal.pkg $ sudo installer -pkg hatch-universal.pkg -target /
以下のコマンドを実行して、Hatchがインストールされていることを確認します。
$ hatch --version Hatch, version 1.11.1
Hatchのコマンド
Hatchにはさまざまなコマンドが用意されています。以下はHatchの主要なコマンドの一覧です。hatch -h
でヘルプを確認できます。
new
: 新しいプロジェクトを作成するpython
: Pythonインタプリターを管理するenv
: プロジェクトの仮想環境を管理するshell
: プロジェクトの仮想環境に入るfmt
: プロジェクトのフォーマットを行うrun
: プロジェクトのスクリプトを実行するbuild
: プロジェクトをビルドするtest
: テストを実行するversion
: プロジェクトのバージョンを表示または更新するconfig
: グローバルな設定を確認するproject
: プロジェクトの情報を確認する
また、各コマンドにサブコマンドがあります。サブコマンドでも-h
でヘルプを確認できます。
$ hatch -h ... $ hatch new -h ... $ hatch python -h ...
まずは新しいプロジェクトを作成し、フォーマッターやリンターを実行してみましょう。
hatchコマンドの入力補完機能
Hatchの機能を見ていく前に、コマンドの入力補完機能を紹介します。
Hatchは多くのコマンドを提供しているため、コマンドを入力する際にタブキーを利用した補完機能があると便利です。公式ドキュメントにいくつかのシェルの補完設定が記載されています。hatchを利用する場合には、補完の設定をしておくと良いでしょう。
他のシェルでの補完設定は、以下のリンクを参照してください。
新しいプロジェクトを作成する
Hatchでは、以下のコマンドを実行して、新しいプロジェクトを作成します。
$ hatch new myproject
コマンドを実行すると、以下のようにプロジェクトが作られ、ファイル一覧が出力されます。
$ hatch new myproject myproject ├── src │ └── myproject │ ├── __about__.py │ └── __init__.py ├── tests │ └── __init__.py ├── LICENSE.txt ├── README.md └── pyproject.toml
pyproject.[build-system]
に"hatchling.
が指定され、[project]
にプロジェクトのメタデータが出力されています。必要に応じてプロジェクトのメタデータを変更してください。
続いて、この初期プロジェクトでHatchの機能を使ってみましょう。
Hatchによるテスト、フォーマット、登録済みのスクリプトの実行
Hatchでは、Hatchとしてすでに登録されているテストやフォーマットの実行、デフォルトで登録済みのスクリプトの実行ができます。
Hatchによるコードフォーマットや静的解析
Hatchではfmt
サブコマンドで、プロジェクトのフォーマットと静的解析ができます。デフォルトでRuffが採用されており、いくつかのルールが設定されています。
hatch fmt
を実行すると、フォーマットと静的解析が行われます。
$ hatch fmt All checks passed! 3 files left unchanged
fmt
サブコマンドには以下のようなオプションがあります。
オプション | 説明 |
---|---|
--check |
フォーマットのチェックを行う |
--preview |
修正箇所を表示する |
--lint , -l |
静的解析のみを行う |
--format , -f |
フォーマットのみを行う |
そのほかのオプションについては、以下の公式サイトを参照してください。
デフォルトで設定されているフォーマッターのルールは以下の通りです。フォーマッターのルールは、プロジェクトのpyproject.
Hatch によるテスト
次にテストについて見てみましょう。test
サブコマンドで実行できます。Hatchではデフォルトでpytestが採用されています。
$ hatch test ============================ test session starts ============================ platform darwin -- Python 3.12.3, pytest-8.2.0, pluggy-1.5.0 rootdir: /Users/gihyo/dev/gihyo-python-monthly_sample/pdfifysvg configfile: pyproject.toml plugins: rerunfailures-14.0, mock-3.14.0, xdist-3.6.1 collected 0 items =========================== no tests ran in 0.00s ===========================
また、test
サブコマンドには以下のオプションがあります。
オプション | 説明 |
---|---|
--randomize , -r |
テストの実行順序をランダムにする |
--parallel , -p |
テスト実行の並列化 |
--cover , -c |
テストのカバレッジを計測 |
--all , -a |
すべてのPythonバージョンでテストを実行 |
--python , -py |
特定のPythonバージョンでテストを実行 |
そのほかのオプションは、以下の公式サイトを参照してください。
Hatchではカバレッジの計測もデフォルトでサポートされています。coverageが利用されています。
$ hatch test -py 3.11 -c ───────────────────────────── hatch-test.py3.11 ───────────────────────────── ============================ test session starts ============================ platform darwin -- Python 3.11.2, pytest-8.2.0, pluggy-1.5.0 rootdir: /Users/gihyo/dev/gihyo-python-monthly_sample/pdfifysvg configfile: pyproject.toml plugins: rerunfailures-14.0, mock-3.14.0, xdist-3.6.1 collected 1 item tests/test_pdfysvg.py . [100%] ============================= 1 passed in 0.12s ============================= Combined data file .coverage.jrfk.local.79827.XpkHLYBx Name Stmts Miss Branch BrPart Cover --------------------------------------------------------------- src/pdfysvg/__init__.py 0 0 0 0 100% src/pdfysvg/__main__.py 1 1 0 0 0% src/pdfysvg/cli/__init__.py 10 0 10 0 100% src/pdfysvg/cli/main.py 11 2 2 1 77% tests/__init__.py 0 0 0 0 100% tests/test_pdfysvg.py 19 0 6 1 96% --------------------------------------------------------------- TOTAL 41 3 18 2 92%
次に、複数のPythonバージョンでのテストを実行してみましょう。pyproject.
テストを実行します。複数のテストが実行されます。
$ hatch test --all ...(長いので割愛) ─────────────────────────────────────────────────────────────────────────────── hatch-test.py3.8 =============================================================================== 1 passed in 0.11s ─────────────────────────────────────────────────────────────────────────────── hatch-test.py3.9 =============================================================================== 1 passed in 0.19s ─────────────────────────────────────────────────────────────────────────────── hatch-test.py3.10 =============================================================================== 1 passed in 0.11s ─────────────────────────────────────────────────────────────────────────────── hatch-test.py3.11 =============================================================================== 1 passed in 0.10s ─────────────────────────────────────────────────────────────────────────────── hatch-test.py3.12 ========================================================================= 1 passed, 1 warning in 0.10s
Hatchによるスクリプトの実行
Hatchでは登録しているスクリプトをrun
サブコマンドで実行できます。また、env show
サブコマンドで、登録しているスクリプトを確認できます。
$ hatch env show Standalone ┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━┓ ┃ Name ┃ Type ┃ Dependencies ┃ Scripts ┃ ┡━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━┩ │ default │ virtual │ │ │ ├─────────┼─────────┼──────────────┼─────────┤ │ types │ virtual │ mypy>=1.0.0 │ check │ └─────────┴─────────┴──────────────┴─────────┘
Hatchではデフォルトでmypyを利用した型チェックのスクリプトが登録されています。登録してあるスクリプトは次のように実行します。
$ hatch run types:check Success: no issues found in 5 source files
スクリプトだけでなく、Pythonのコードを直接実行することもできます。
$ hatch run python -c "print('Hello, Hatch!')" Hello, Hatch!
HatchでのPythonインタープリターの管理
hatchではPythonインタープリターの管理も行うことができます。以下のコマンドを実行して、利用可能なPythonのバージョンを表示します。
$ hatch python show Available ┏━━━━━━━━━━┳━━━━━━━━━┓ ┃ Name ┃ Version ┃ ┡━━━━━━━━━━╇━━━━━━━━━┩ │ 3.8 │ 3.8.19 │ ├──────────┼─────────┤ │ 3.9 │ 3.9.19 │ ├──────────┼─────────┤ │ 3.10 │ 3.10.14 │ ├──────────┼─────────┤ │ 3.11 │ 3.11.9 │ ├──────────┼─────────┤ │ 3.12 │ 3.12.3 │ ├──────────┼─────────┤ │ pypy2.7 │ 7.3.15 │ ├──────────┼─────────┤ │ pypy3.9 │ 7.3.15 │ ├──────────┼─────────┤ │ pypy3.10 │ 7.3.15 │ └──────────┴─────────┘
必要なPythonのバージョンをインストールするには、以下のコマンドを実行します。
$ hatch python install 3.12 Installed 3.12 @ /Users/gihyo/Library/Application Support/hatch/pythons/3.12
これらのPythonインタープリターは自分のPC内で共通で管理されます。また、すべてのPythonインタープリターをインストールしておくには、以下のコマンドを実行します。
$ hatch python install all Installed 3.8 @ /Users/gihyo/Library/Application Support/hatch/pythons/3.8 Installed 3.9 @ /Users/gihyo/Library/Application Support/hatch/pythons/3.9 Installed 3.10 @ /Users/gihyo/Library/Application Support/hatch/pythons/3.10 Installed 3.11 @ /Users/gihyo/Library/Application Support/hatch/pythons/3.11 The latest version is already installed: 3.12 Installed pypy2.7 @ /Users/gihyo/Library/Application Support/hatch/pythons/pypy2.7 Installed pypy3.9 @ /Users/gihyo/Library/Application Support/hatch/pythons/pypy3.9 Installed pypy3.10 @ /Users/gihyo/Library/Application Support/hatch/pythons/pypy3.10
HatchでのPythonインタープリターの管理の注意点
注意点として、2点あります。
1つめは、hatch python
とすると、インストールしたPythonへのUSERPATHが追加される点です。ご自身ですでにPythonインタープリターを管理している場合は、注意してください。PATHを追加したくない場合には、--private
オプションを指定します。
$ hatch python install --private 3.12
2つめは、公式サイトにもありますが、Hatchではマイナーバージョンを指定したPythonインタープリターの管理ができません。Hatchで管理されている以外のバージョンのPythonインタプリターを利用する場合には、pyenvなど別のツールで管理する必要があります。
仮想環境の管理
Hatchでプロジェクト固有の仮想環境を管理していきましょう。1つのプロジェクトの中で複数の仮想環境を持つことができ、それぞれの仮想環境に依存するライブラリを管理できます。依存関係の管理は、pyproject.
デフォルトではdefault
とtypes
の仮想環境があります。 env show
サブコマンドで仮想環境を確認しましょう。
$ hatch env show Standalone ┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━┓ ┃ Name ┃ Type ┃ Dependencies ┃ Scripts ┃ ┡━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━┩ │ default │ virtual │ │ │ ├─────────┼─────────┼──────────────┼─────────┤ │ types │ virtual │ mypy>=1.0.0 │ check │ └─────────┴─────────┴──────────────┴─────────
仮想環境を有効にするには、shell
サブコマンドを実行します。
$ hatch shell source "/Users/gihyo/Library/Application Support/hatch/env/virtual/myproject/xxxxx/myproject/bin/activate"
以下のコマンドで、仮想環境から抜けることができます。
$ exit
types
に入る場合には、以下のように実行します。
$ hatch shell types source "/Users/gihyo/Library/Application Support/hatch/env/virtual/myproject/xxxxx/types/bin/activate"
仮想環境を削除するには、以下のコマンドを実行します。
$ hatch env remove default
依存関係の管理
プロジェクトに必要なライブラリの管理と、それぞれの仮想環境に必要なライブラリを管理について説明します。
必要なライブラリは、pyproject.
まずプロジェクトに必要なライブラリは[project]
セクションのdependencies
に追加しましょう。このセクションに追加したライブラリは、プロジェクトのすべての仮想環境で利用できます。以下の例ではhttpx
を追加しています。
プロジェクトの依存関係は、dep
サブコマンドで確認できます。
$ hatch dep show table Project ┏━━━━━━━┓ ┃ Name ┃ ┡━━━━━━━┩ │ httpx │ └───────┘
Hatchでuvを利用するには
Hatchでuvを利用する場合、pyproject.
Hatchによる仮想環境の追加とスクリプトの登録・実行
仮想環境の追加、仮想環境への依存ライブラリの追加、スクリプトの登録、スクリプトの実行について紹介します。ここではドキュメンテーションツールのSphinxを例に説明します。
はじめに仮想環境と依存ライブラリを追加します。pyproject.[tool.
が仮想環境のセクションです。この場合、docs
という名前の仮想環境を作成します。extra-dependencies
が仮想環境への依存ライブラリを追加するセクションです。この場合、sphinx
とsphinx_
を追加します。
登録した仮想環境と依存関係をenv show
サブコマンドで確認します。docs
環境の依存に、sphinx
とsphinx_
が追加されていることがわかります。
$ hatch env show Standalone ┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓ ┃ Name ┃ Type ┃ Dependencies ┃ Scripts ┃ ┡━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩ │ default │ virtual │ │ │ ├─────────┼─────────┼─────────────────┼─────────┤ │ types │ virtual │ mypy>=1.0.0 │ check │ ├─────────┼─────────┼─────────────────┼─────────┤ │ docs │ virtual │ sphinx │ │ │ │ │ sphinx-material │ │ └─────────┴─────────┴─────────────────┴─────────┘
shell
サブコマンドでdocs
仮想環境に入り、 Sphinxの初期設定を行います。Sphinxの初期設定の詳細は、Sphinxのドキュメントを参照してください。
$ hatch shell docs $ sphinx-quickstart docs ... Finished: An initial directory structure has been created. ... $ exit
次に、Sphinxのビルドスクリプトを登録します。pyproject.[tool.
がセクションです。この場合、build
という名前のスクリプトを登録します。
登録したスクリプトをenv show
サブコマンドで確認します。docs
環境のスクリプトにbuild
が登録されていることがわかります。
$ hatch env show Standalone ┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓ ┃ Name ┃ Type ┃ Dependencies ┃ Scripts ┃ ┡━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩ │ default │ virtual │ │ │ ├─────────┼─────────┼─────────────────┼─────────┤ │ types │ virtual │ mypy>=1.0.0 │ check │ ├─────────┼─────────┼─────────────────┼─────────┤ │ docs │ virtual │ sphinx │ build │ │ │ │ sphinx-material │ │ └─────────┴─────────┴─────────────────┴─────────┘
実行してみましょう。次のコマンドで実行します。hatch run
コマンドにName:Scripts
でスクリプトを指定します。
$ hatch run docs:build ... build succeeded, 1 warning. The HTML pages are in docs/_build/html.
プロジェクト自体には影響を与えず、特定の仮想環境にのみ必要なライブラリを追加し、スクリプトを登録して実行が簡単にできます。簡単に美しいドキュメントを作成できました。
プロジェクトのビルド、デプロイ
HatchはPythonパッケージのビルドのバックエンドに、Hatchlingを使用しています。
Hatchlingは、Python公式のPackaging User Guideでも設定方法が紹介されているビルドツールで、多くのサードパーティーライブラリで利用されています。
ビルドは以下のコマンドで実行できます。distディレクトリにsdistとwheelが作成されます。
$ hatch build ────────────────────────────────────────── sdist ─────────────────────────────────────────── dist/myproject-0.0.1.tar.gz ────────────────────────────────────────── wheel ─────────────────────────────────────────── dist/myproject-0.0.1-py3-none-any.whl
デプロイにはpublish
サブコマンドを利用します。どのリポジトリにデプロイするかは、pyproject.
またいくつかの手順が追加で必要です。詳細については、公式ドキュメントをご参照ください。
Hatchによるプロジェクトのバージョン管理
以下のコマンドで、プロジェクトのバージョンを表示できます。
$ hatch version myproject, version 0.1.0
バージョンを更新するには、以下のコマンドを実行します。
$ hatch version 0.2.0 myproject, version 0.2.0
まとめ
細かい設定を気にせず、サクッと新しいPythonプロジェクトを作りたいときには、Hatchが便利です。
Hatchは、uvやRuff同様、まだまだ開発途中で日々進化をしており、開発もとても活発です。本記事で紹介した内容はHatchの一部ですが、Hatchの公式ドキュメントにはさらに多くの機能が記載されています。うまく動かない場合は、公式ドキュメントを参照してください。
また今年のPyCon US 2024にて、今回取り上げた