Closed7

「Hatch」を試す

kun432kun432

GitHubレポジトリ

https://github.com/pypa/hatch

Hatch

Hatch は、モダンで拡張可能な Python プロジェクトマネージャです。

特長

詳細は Why Hatch? ページをご覧ください。

ドキュメント

ドキュメントMaterial for MkDocs を使用して作成され、GitHub Pages によってホストされています。

ライセンス

Hatch は MIT ライセンスの条件のもとで配布されています。

公式ドキュメント

https://hatch.pypa.io/latest/

kun432kun432

Introduction

https://hatch.pypa.io/latest/intro/

hatch newでプロジェクトを作成する。

hatch new "Hatch Demo"
出力
hatch-demo
├── src
│   └── hatch_demo
│       ├── __about__.py
│       └── __init__.py
├── tests
│   └── __init__.py
├── LICENSE.txt
├── README.md
└── pyproject.toml

ディレクトリを見ると出力通りに作成されている

tree -a hatch-demo
出力
hatch-demo/
├── LICENSE.txt
├── README.md
├── pyproject.toml
├── src
│   └── hatch_demo
│       ├── __about__.py
│       └── __init__.py
└── tests
    └── __init__.py

4 directories, 6 files

作成された各ファイルの中身は以下。なお、自分の名前やメアドは ~/.gitconfig から取得しているっぽい。

README.md
# Hatch Demo

[![PyPI - Version](https://img.shields.io/pypi/v/hatch-demo.svg)](https://pypi.org/project/hatch-demo)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/hatch-demo.svg)](https://pypi.org/project/hatch-demo)

-----

## Table of Contents

- [Installation](#installation)
- [License](#license)

## Installation

```console
pip install hatch-demo
```

## License

`hatch-demo` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
pyproject.toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "hatch-demo"
dynamic = ["version"]
description = ''
readme = "README.md"
requires-python = ">=3.8"
license = "MIT"
keywords = []
authors = [
  { name = "kun432", email = "kun432@users.noreply.github.com" },
]
classifiers = [
  "Development Status :: 4 - Beta",
  "Programming Language :: Python",
  "Programming Language :: Python :: 3.8",
  "Programming Language :: Python :: 3.9",
  "Programming Language :: Python :: 3.10",
  "Programming Language :: Python :: 3.11",
  "Programming Language :: Python :: 3.12",
  "Programming Language :: Python :: Implementation :: CPython",
  "Programming Language :: Python :: Implementation :: PyPy",
]
dependencies = []

[project.urls]
Documentation = "https://github.com/kun432/hatch-demo#readme"
Issues = "https://github.com/kun432/hatch-demo/issues"
Source = "https://github.com/kun432/hatch-demo"

[tool.hatch.version]
path = "src/hatch_demo/__about__.py"

[tool.hatch.envs.types]
extra-dependencies = [
  "mypy>=1.0.0",
]
[tool.hatch.envs.types.scripts]
check = "mypy --install-types --non-interactive {args:src/hatch_demo tests}"

[tool.coverage.run]
source_pkgs = ["hatch_demo", "tests"]
branch = true
parallel = true
omit = [
  "src/hatch_demo/__about__.py",
]

[tool.coverage.paths]
hatch_demo = ["src/hatch_demo", "*/hatch-demo/src/hatch_demo"]
tests = ["tests", "*/hatch-demo/tests"]

[tool.coverage.report]
exclude_lines = [
  "no cov",
  "if __name__ == .__main__.:",
  "if TYPE_CHECKING:",
]
src/hatch_demo/__about__.py
# SPDX-FileCopyrightText: 2025-present kun432 <kun432@users.noreply.github.com>
#
# SPDX-License-Identifier: MIT
__version__ = "0.0.1"
src/hatch_demo/__init__.py
# SPDX-FileCopyrightText: 2025-present kun432 <kun432@users.noreply.github.com>
#
# SPDX-License-Identifier: MIT
tests/__init__.py
# SPDX-FileCopyrightText: 2025-present kun432 <kun432@users.noreply.github.com>
#
# SPDX-License-Identifier: MIT
LICENSE.txt
MIT License

Copyright (c) 2025-present kun432 <kun432@users.noreply.github.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

なお、すでにプロジェクトが存在している場合は、そのディレクトリに入ってから--initをつけてhatch newすると対話形式で設定するみたい。また、setup.py がある場合は setuptools の設定を自動的に行って移行してくれるらしい。

なお、自分はpyproject.toml、ずっと雰囲気でしかやってないので全然理解できていない・・・Hatchで作成したデフォルトのものについて o4-mini に聞いてみた。

pyproject.toml

以下では、ご提示の pyproject.toml に含まれる各セクションと主要設定項目について、その役割や意味を順に解説します。

本設定ファイルは、Python のビルドシステム規格である PEP 518/517 に準拠しつつ、プロジェクトメタデータ定義の PEP 621 に沿っており、ビルドバックエンドに Hatchling を利用、プロジェクト情報は動的バージョン取得を含めた project セクションで管理しています。さらに、Hatch のバージョンプラグインや環境(envs)の設定、Coverage.py によるテストカバレッジ測定の設定も含まれており、いわば開発→テスト→リリースまでのフローを一つのファイルで統一的に扱える構成です。

[build-system]

  • requires
    ビルド時に必要なパッケージを列挙します。ここでは "hatchling" を指定し、Hatchling をビルドバックエンドとして動作させるための依存を明示しています (peps.python.org)。
  • build-backend
    実際にビルド処理を担うモジュールを指定します。PEP 517 では、ここに指定したバックエンドがソースディレクトリから配布アーカイブ等を生成します。"hatchling.build" は Hatchling のビルド機能を利用する設定です (github.com)。

[project]

  • name
    パッケージ名です。PyPI に公開する際の識別子となります (peps.python.org)。
  • dynamic
    "version" のように、静的ではなくビルド時に自動取得・挿入するフィールドを列挙する PEP 621 の機能です (peps.python.org)。
  • descriptionreadme
    短い説明文と、詳細説明を記載したファイル(例:README.md)を指定します (peps.python.org)。
  • requires-python
    サポート対象の Python バージョン範囲を指定します。ここでは >=3.8 以降を必須としています (setuptools.pypa.io)。
  • license
    パッケージのライセンスを明示します。"MIT" はオープンソースの MIT ライセンスを表します (peps.python.org)。
  • keywords, authors, classifiers
    検索時のタグや、開発者情報、PyPI 上の分類情報(開発ステータス、対応 Python バージョンなど)を指定します (peps.python.org)。
  • dependencies
    インストール時に必須となるパッケージ一覧を記載します。空リストなら依存なしを意味します (peps.python.org)。

[project.urls]

  • Documentation, Issues, Source
    各種リソースへの URL をキー付きで登録することで、PyPI 上のプロジェクト情報ページにリンクとして表示されます (peps.python.org)。

[tool.hatch.version]

  • path
    Hatch のバージョンプラグインにおいて、正規表現等で動的にバージョンを取得・更新する対象ファイルを指定します。ここでは内部に __version__ などを持つ src/hatch_demo/__about__.py を参照します (hatch.pypa.io)。

[tool.hatch.envs.types]

  • extra-dependencies
    この環境(ここでは types)を構築する際に追加インストールするパッケージを列挙します。例えば型チェック用の mypy>=1.0.0 を指定しています (hatch.pypa.io)。
  • [tool.hatch.envs.types.scripts]
    環境内で実行できるショートカットスクリプトを定義します。check = "mypy --install-types --non-interactive {args:...}" のように、引数展開を含めた形でコマンドを登録可能です (hatch.pypa.io)。

[tool.coverage.run]

  • source_pkgs
    カバレッジ測定対象とするパッケージ(モジュール)のリストです。ここでは hatch_demotests を指定しています (coverage.readthedocs.io)。
  • branch
    分岐網羅を有効化し、if/else 分岐の実行状況も測定します (coverage.readthedocs.io)。
  • parallel
    並列測定(サブプロセス計測)結果をプロセス別に一時ファイル出力し、後で結合できるようにします (coverage.readthedocs.io)。
  • omit
    測定から除外するファイルパターンを列挙します。ここではバージョン定義ファイルなどを除外しています (coverage.readthedocs.io)。

[tool.coverage.paths]

  • hatch_demo, tests
    実際のソース配置パスと、CI 等で異なるディレクトリ構造になった場合のマッピングを定義します。複数パスを指定すると、カバレッジデータ結合時に対応するファイル同士をマージできます (discuss.python.org)。

[tool.coverage.report]

  • exclude_lines
    レポート生成時に除外する行を正規表現で指定します。例外やメインガード、型チェック用コード等をカウント対象から外せます (coverage.readthedocs.io)。

以上が、典型的な pyproject.toml における主要な設定項目の解説です。これらを組み合わせることで、依存管理からテストカバレッジ測定、環境構築、バージョン管理までを一元的に制御できます。

以下にも説明がある

https://hatch.pypa.io/latest/config/metadata/#license

kun432kun432

Environments

Hatchで仮想環境も作成できる。

Directoryに入る。

cd hatch-demo

pyproject.tomldependencies を追加する。

pyproject.toml
(snip)
dependencies = [
    "cowsay"
]

仮想環境を作成するにはhatch env create

hatch env create

ただし .venvのようなものはできていない。どこにあるんだろう?ということで、hatch env findで探してみる。

hatch env find

こんなところに・・・

出力
/Users/kun432/Library/Application Support/hatch/env/virtual/hatch-demo/Xf-p92xR/hatch-demo

仮想環境に入るには hatch shell

hatch shell

アクティベートされてる。

出力
source "/Users/kun432/Library/Application Support/hatch/env/virtual/hatch-demo/Xf-p92xR/hatch-demo/bin/activate"
(hatch-demo) $

環境はこんな感じだった。

(hatch-demo) $ which python
/Users/kun432/Library/Application Support/hatch/env/virtual/hatch-demo/Xf-p92xR/hatch-demo/bin/python

(hatch-demo) $ python --version
Python 3.13.5

なるほど、Python本体も管理されると。

追加したdependenciesもインストールされていた。

(hatch-demo) $ which cowsay
/Users/kun432/Library/Application Support/hatch/env/virtual/hatch-demo/Xf-p92xR/hatch-demo/bin/cowsay
cowsay -t "こんにちは!"
出力
  ______
| こんにちは! |
  ======
      \
       \
         ^__^
         (oo)\_______
         (__)\       )\/\
             ||----w |
             ||     ||

仮想環境から抜けるには exit

(hatch-demo) $ exit
$

deactivateでも仮想環境から抜けているように見えるんだけど、hatchの管理上はdeactivateだとどうやら仮想環境から抜けてないみたいなので、exitを使うで良さそう。(hatch shellはサブシェル起動してるように見える)

$ hatch shell
(hatch-demo) $ deactivate
$ hatch shell
Already in environment: default

仮想環境に入らずにそのまま実行することもできる。hatch run

hatch run cowsay -t "こんにちは!"
出力
  ______
| こんにちは! |
  ======
      \
       \
         ^__^
         (oo)\_______
         (__)\       )\/\
             ||----w |
             ||     ||

なお、dependencies は pyprojects.toml に追加したあと、仮想環境シェルに入るか、コマンドを実行すれば、どうやらオンデマンド的にインストールされるみたい。

また、複数の仮想環境をインストールして、実行時に選択することもできるみたい。hatch env show で仮想環境の一覧を確認できる。

hatch env show

デフォルトだと以下の2つの環境が作成されている。

出力
                  Standalone
┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Name    ┃ Type    ┃ Dependencies ┃ Scripts ┃
┡━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ default │ virtual │              │         │
├─────────┼─────────┼──────────────┼─────────┤
│ types   │ virtual │ mypy>=1.0.0  │ check   │
└─────────┴─────────┴──────────────┴─────────┘

defaulttypes という2つの仮想環境があり、types には mypyが有効になっている様子。違いを見てみる。まずデフォルトに入ってみる。

$ hatch shell
(hatch-demo) $ pip freeze | grep -i mypy
(hatch-demo) $                             # 何も出力されない

(hatch-demo) $ which mypy
(hatch-demo) $                             # 何も出力されない

(hatch-demo) $ exit

次にtypesに入ってみる。実際にはいろいろdependenciesなどがインストールされるログも出力される。

$ hatch shell types
(types) $

typesの仮想環境に入ったので、mypyを確認してみる

(types) $ pip freeze | grep -i mypy
mypy==1.16.1
mypy_extensions==1.1.0

(types) $ which mypy
/Users/kun432/Library/Application Support/hatch/env/virtual/hatch-demo/Xf-p92xR/types/bin/mypy

(types) $ exit
$

なるほど、別々の環境が用意されているというわけか。この辺の設定は、pyproject.toml の以下で設定されている。

pyproject.toml
(snip)
[tool.hatch.envs.types]
extra-dependencies = [
  "mypy>=1.0.0",
]
(snip)

また環境ごとにコマンドを設定できる。以下の例だとhatch run types:check でmypyによる型チェックが実行される。

pyproject.toml
(snip)
[tool.hatch.envs.types.scripts]
check = "mypy --install-types --non-interactive {args:src/hatch_demo tests}"
(snip)
hatch run types:check
出力
Success: no issues found in 3 source files

こういった環境やツールをマトリックス的に組み合わせることもできるってのがドキュメントにある例。

pyproject.toml
[tool.hatch.envs.test]
dependencies = [
  "pytest"
]

[tool.hatch.envs.test.scripts]
check = "pytest"

[[tool.hatch.envs.test.matrix]]
python = ["3.10", "3.11"]
version = ["42", "3.14"]

[[tool.hatch.envs.test.matrix]]
python = ["3.11", "3.12"]
version = ["9000"]
feature = ["foo", "bar"]

環境の一覧を見てみる。

hatch env show
出力
                  Standalone
┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Name    ┃ Type    ┃ Dependencies ┃ Scripts ┃
┡━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ default │ virtual │              │         │
├─────────┼─────────┼──────────────┼─────────┤
│ types   │ virtual │ mypy>=1.0.0  │ check   │
└─────────┴─────────┴──────────────┴─────────┘
                             Matrices
┏━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Name ┃ Type    ┃ Envs                 ┃ Dependencies ┃ Scripts ┃
┡━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ test │ virtual │ test.py3.10-42       │ pytest       │ test    │
│      │         │ test.py3.10-3.14     │              │         │
│      │         │ test.py3.11-42       │              │         │
│      │         │ test.py3.11-3.14     │              │         │
│      │         │ test.py3.11-9000-foo │              │         │
│      │         │ test.py3.11-9000-bar │              │         │
│      │         │ test.py3.12-9000-foo │              │         │
│      │         │ test.py3.12-9000-bar │              │         │
└──────┴─────────┴──────────────────────┴──────────────┴─────────┘

例えばこんな感じで実行できる。

hatch run test.py3.11-42:test
出力
======================== test session starts =========================
platform darwin -- Python 3.11.10, pytest-8.4.1, pluggy-1.6.0
rootdir: /Users/kun432/work/hatch-demo
configfile: pyproject.toml
collected 0 items

======================= no tests ran in 0.00s ========================
hatch run test.py3.10-42:test
出力
======================== test session starts =========================
platform darwin -- Python 3.10.16, pytest-8.4.1, pluggy-1.6.0
rootdir: /Users/kun432/work/hatch-demo
configfile: pyproject.toml
collected 0 items

======================= no tests ran in 0.00s ========================

仮想環境の削除は、 1つの仮想環境ならhatch env remove 環境名 、まとめて全部なら hatch env prune

kun432kun432

gihyo.jpの記事ができることがまとまっていてわかりやすい。

https://gihyo.jp/article/2024/05/monthly-python-2405

  • 上記のようにテスト環境を作らなくても hatch testでテストやカバレッジ計測ができる。マトリックスの書き方はちょっと変わるみたい。
  • hatch formatでruffがフォーマッター・リンターとして実行される。ルールもデフォルトで用意されている(pyproject.toml で自分で設定することもできる)
  • uvも組み合わせることができるらしいが、いまいち使い方がわからなかった。
kun432kun432

まとめ

自分はPythonのコードを書き始めてからそれほどの時間が経っていないので、このあたりの環境設定などについては特に良くわかってない。そんな自分の勝手な印象をまとめると、

  • PyPIのパッケージをビルドして作るとかには良さそう
  • 開発で使うようなツールチェインの設定をある程度デフォルトでよしなにやってくれそう

という感じ。

自分は uv も使っているけど、全部理解できているわけではない。ただ、全部の機能を使うわけでもないので、必要な機能だけ使うにあたってはミニマムで使えている。ただ、何かしらのプロジェクトで設定もきちんとやって、みたいなことを考えると、まあ正直知識が追いついていないというところはあるので、ある程度おまかせできるのはありがたい面もありそう。(細かくこだわりだすと何がベストなのか?で悩むことにもなりそうだし)

このスクラップは2ヶ月前にクローズされました