5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python環境構築:requirements.txtからpyproject.tomlへ——設定ファイルの役割を整理して移行する

5
Last updated at Posted at 2026-06-29

はじめに

最近、AIと一緒にPythonツールをいくつか作っていて、こんなことに気づきました。

プロジェクトによって、設定ファイルの構成がバラバラ。

あるプロジェクトには requirements.txtpytest.ini があって、別のプロジェクトには pyproject.toml だけがある。conftest.py はどこにでも出てくる。何が正解なのか、そもそも「旧来スタイル」と「モダンスタイル」という区別があること自体、最初はわかっていませんでした。

この記事では、実際に requirements.txt + pytest.ini 構成から pyproject.toml に移行した経験をもとに、各ファイルの役割と移行手順を整理します。


対象読者

  • Python を書き始めて間もない方
  • requirements.txt は使ったことがあるが pyproject.toml はよくわからない方

設定ファイルの全体像

まず登場する設定ファイルを整理します。大きく「旧来スタイル」と「モダンスタイル」に分かれています。

旧来スタイル(requirements.txt 方式)

設定が複数ファイルに分散しているのが特徴です。

ファイル 役割
requirements.txt 依存パッケージの一覧。pip install -r requirements.txt で使う
pytest.ini pytestの動作設定(テストパス・オプションなど)
setup.py / setup.cfg パッケージとして配布する場合のメタデータ設定(最近は新規ではあまり書かない)
.flake8 / mypy.ini LinterやType checkerごとの個別設定ファイル

モダンスタイル(pyproject.toml 方式)

pyproject.toml 1ファイルに集約するのが思想です。

セクション 役割
[project] パッケージ名・バージョン・依存パッケージ(requirements.txtの代替)
[tool.pytest.ini_options] pytestの動作設定(pytest.iniの代替)
[tool.mypy] / [tool.ruff] 各ツールの設定(個別ファイルの代替)
[build-system] ビルドバックエンドの指定

conftest.py はどちらでも使う

conftest.py はpytestのファイルであり、旧来・モダンどちらのスタイルとも無関係です。pytestを使う限り、すべてのプロジェクトで登場します。

ファイル 役割 スタイルとの関係
conftest.py テスト共通fixture・フックの定義 スタイル無関係。pytestを使う全プロジェクトで使用
pytest.ini pytestの動作設定 旧来スタイルで使う
[tool.pytest.ini_options] pytestの動作設定 モダンスタイルで使う(pytest.iniの代替)

移行前のファイル構成

今回の移行対象はこちらです。

csv-analyzer/
├── csv_analyzer.py           # メインの解析ロジック
├── cli.py                    # CLIコマンド定義(click)
├── conftest.py               # テストの共通処理(フィクスチャなど)
├── pytest.ini                # pytestの全体設定
├── requirements.txt          # 依存パッケージ一覧
├── README.md
└── tests/
    ├── test_csv_analyzer.py
    └── test_cli.py

移行前の各ファイル:

# requirements.txt
click>=8.0.0
pytest>=7.0.0
# pytest.ini
[pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = --cov=. --cov-report=term-missing
filterwarnings =
    ignore::pytest.PytestCollectionWarning
# conftest.py
import sys
import os

# プロジェクトルートを sys.path に追加する
sys.path.insert(0, os.path.dirname(__file__))

pyproject.toml への移行

Step 1:[project] — 依存パッケージの整理

requirements.txt の内容を移行します。ポイントは本番依存と開発依存を分離することです。

  • click はアプリ本体で使うので dependencies(本番依存)へ
  • pytest は開発時だけ必要なので optional-dependencies(開発依存)へ
[project]
name = "csv-analyzer"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
    "click>=8.0.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0.0",
]

インストールコマンドは以下のように変わります。

# 移行前
pip install -r requirements.txt

# 移行後(本番依存のみ)
pip install .

# 移行後(開発・テスト用依存も含む)
pip install -e ".[dev]"

Step 2:[tool.pytest.ini_options] — pytest設定の移行

pytest.ini の内容を移行します。TOMLでは値の型(配列・文字列)に注意が必要です。

pytest.ini との対応関係はこうなります。

pytest.ini pyproject.toml 変更点
testpaths = tests testpaths = ["tests"] 配列になる
python_files = test_*.py python_files = ["test_*.py"] 配列・クォートが必要
python_classes = Test* python_classes = ["Test*"] 配列・クォートが必要
python_functions = test_* python_functions = ["test_*"] 配列・クォートが必要
addopts = --cov=. --cov-report=term-missing addopts = ["--cov=.", "--cov-report=term-missing"] 要素ごとに分割
filterwarnings = ignore::... filterwarnings = ["ignore::..."] 配列になる

また、conftest.py にあった sys.path.insert(...)pythonpath 設定で代替できます。

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = ["--cov=.", "--cov-report=term-missing"]
filterwarnings = ["ignore::pytest.PytestCollectionWarning"]
pythonpath = ["."]   # conftest.py の sys.path.insert(...) の代替

これにより conftest.py のパス操作は不要になります。

Step 3:[build-system] — ビルド設定の追加

pip install -e ".[dev]" を動かすために必要な設定です。

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
  • requires:ビルド時にpipが自動でインストールするツール
  • build-backend:実際にビルドを担当するツールの指定

Step 4:[tool.setuptools] — フラットレイアウトへの対処

今回のプロジェクトは cli.pycsv_analyzer.py がルート直下に並んでいます。この構成(フラットレイアウト)では、setuptools がどちらをパッケージ本体にすべきか判断できずエラーになります。

error: Multiple top-level modules discovered in a flat-layout: ['cli', 'csv_analyzer'].

py-modules で明示的に列挙することで解決します。

[tool.setuptools]
py-modules = ["csv_analyzer", "cli"]

完成した pyproject.toml

[project]
name = "csv-analyzer"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
    "click>=8.0.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0.0",
]

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

[tool.setuptools]
py-modules = ["csv_analyzer", "cli"]

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = ["--cov=.", "--cov-report=term-missing"]
filterwarnings = ["ignore::pytest.PytestCollectionWarning"]
pythonpath = ["."]

移行後のファイル構成

csv-analyzer/
├── csv_analyzer.py           # メインの解析ロジック
├── cli.py                    # CLIコマンド定義(click)
├── conftest.py               # テストの共通処理(フィクスチャなど) ※sys.path操作は削除
├── pyproject.toml            # 依存パッケージ・ツール設定(一元管理)
├── README.md
└── tests/
    ├── test_csv_analyzer.py
    └── test_cli.py

pytest.inirequirements.txt が消え、pyproject.toml 1ファイルに集約されました。


ハマりどころ

① build-backend の誤記

# NG:内部APIで直接使用を意図していない非推奨の旧形式
build-backend = "setuptools.backends.legacy:build"

# OK
build-backend = "setuptools.build_meta"

② フラットレイアウトエラー

ルート直下に .py ファイルが複数ある場合、[tool.setuptools] py-modules の指定が必要です。src/ 配下にソースをまとめる「srcレイアウト」にする方法もあります。


まとめ:移行チェックリスト

次のプロジェクトで pyproject.toml に移行するときの確認リストです。

□ [project] dependencies に本番依存パッケージを記載したか
□ [project.optional-dependencies] dev に開発・テスト依存を分離したか
□ [build-system] を追加したか(build-backend = "setuptools.build_meta")
□ ルート直下に .py ファイルが複数ある場合、[tool.setuptools] py-modules を追加したか
□ pytest.ini の内容を [tool.pytest.ini_options] に移行したか(値は配列で記載)
□ conftest.py の sys.path 操作を pythonpath 設定に置き換えたか
□ requirements.txt と pytest.ini を削除したか

おわりに

pyproject.toml は最初とっつきにくく感じましたが、各セクションの役割を理解すると「設定が1ファイルにまとまっている」ことの快適さがわかります。AIと一緒に開発する場合も、最初にこの構成を伝えておくと一貫したスタイルでコードを生成してもらいやすくなります。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?