uvを使って理想的なPythonプロジェクトを構築する
uvを利用したPythonプロジェクト環境のテンプレート
以前、poetry を利用した Python のプロジェクトテンプレートを作成しました。
今回は、よりモダンな開発環境を整えるために、Rust 製の注目のパッケージマネージャー uv
を活用して、新たな Python プロジェクトテンプレートを作りました。
どのような環境を作ったのか特徴など簡単に紹介します。
uv について簡単に
Python のパッケージ管理について、pip
や poetry
などで行われてきましたが、Rust 製で高速に依存関係を解決できる uv
が自分の中で熱いです。
uv uses aggressive caching to avoid re-downloading (and re-building) dependencies that have already been accessed in prior runs.
上記のように公式でもコンセプトで掲げられている通り、キャッシュを効率的に活用して処理が高速です。
また、個人的には使っていた poetry
とコマンドが似ている部分が多かったり、pyproject.toml の形式でプロジェクトを管理したり、習得が簡単そうだなと感じた点も魅力でした。
詳しくはConceptsにて解説されています。
uv を使ったプロジェクトテンプレートの紹介とポイント
Python プロジェクトをスムーズに開始するために、uv
を活用したプロジェクトテンプレートを作成しました。このテンプレートでは、開発時に必要なツールを適切に分類し、プロジェクトの品質と保守性を向上させることを目的としています。各ツールの導入理由やその利点について簡単に説明します。
コード品質とフォーマット
コードの可読性と一貫性を向上させ、チーム開発時のコードスタイルの統一とコードの品質を保つために、以下のツールを導入しています。
-
isort
:インポートの並び順を整理し、コードの一貫性を維持 -
ruff
:flake8
やblack
の代替として、高速なコードフォーマットと静的解析を実施(しかも uv と同じ Astral 社製。vscode の拡張機能の recommend にも設定) -
lizard
:コードのサイクロマティック複雑度を測定し、保守しやすいコードを促進
静的解析とセキュリティ
コードのバグやセキュリティリスクを早期検出するために、以下のツールを導入しています。
-
mypy
:型チェックを行い、実行前に潜在的なバグを検出(vscode の拡張機能の recommend にも設定) -
pyright
:mypy
と同じ静的型チェッカー。VS Code では Pylanceを使用(recommend にも設定) -
bandit
:Python のセキュリティ脆弱性をスキャンし、安全なコードの実装を支援 -
pip-audit
:GitHub Advisory Database を使用し依存関係のセキュリティリスクを検出し、脆弱性のあるパッケージの使用を防ぐ -
licensecheck
:プロジェクトの依存関係のライセンスをチェックし、コンプライアンスを確保
テストツール
品質保証のために、包括的なテスト環境を構築します。
-
pytest
:シンプルかつ拡張性の高いテストフレームワーク。 -
pytest-cov
:コードカバレッジを測定し、テストの網羅率を可視化 -
pytest-mock
:pytest 用のモック(unittest.mock
互換) -
hypothesis
:プロパティベースのテストを提供し、多様な入力データでコードの動作を検証
自動化
開発の効率を上げるために、以下のツールを導入しています。
-
nox
:環境ごとのテストやビルドプロセスを自動化 -
pre-commit
:コミット時やプッシュ時にコードフォーマットや静的解析、テストなどを自動実行 -
pre-commit-hooks
:pre-commit
を利用するためのすぐに使える hooks(check-toml とか、end-of-file-fixer とか)
ドキュメント生成
プロジェクトのドキュメントを簡単に管理するために、以下のツールを採用しました。
-
sphinx
:Python 向けのドキュメント生成ツール-
furo
:sphinx
のモダンなドキュメントテーマ -
sphinx-copybutton
: Sphinx ドキュメントのコードブロックにコピーボタンを追加する拡張機能
-
-
myst-parser
:Markdown を Sphinx で使用可能に -
nbsphinx
:Jupyter Notebook を Sphinx ドキュメントに直接組み込む -
jupytext
:Jupyter Notebook と python ファイルを相互に変換するツール
uv での Python プロジェクトの活用方法各種
環境のセットアップ
以下の手順に従って、 uv
の Python プロジェクトを使えるようになるまでのセットアップを行います。
-
仮想環境を作成する
下記のコマンドを実行することで、プロジェクトディレクトリ内の
.venv
に設定している Python や開発ツールなどのパッケージをインストールします。uv sync source .venv/bin/activate # Windows の場合は .venv\Scripts\activate
→
uv
の仮想環境内でruff check
などのツールを実行できます。 -
pre-commit の初期設定
pre-commit
の特定の hook を利用するために、下記の git hook script を導入します(参考)。uv run pre-commit install -t pre-commit -t pre-push
→
pre-commit
により、コミット時の処理やプッシュ時の処理が実行されるようになります。
環境の設定について
VS Code の設定
基本は VS Code 利用前提のプロジェクトを想定しているので、 extensions.json
や settings.json
を設定しています。
Python プロジェクトでの活用と言う観点で拡張機能を選んでいますが、絶対入れておきたいのが Ruff
、 Pylance
と mypy
です。これらがないと Python を書くのが辛くなるほど便利です。
設定は好みによりますが、 .nox
や .venv
ディレクトリを検索やファイル監視から除外しています。一応 .editorconig
も用意していますが、お好みで自由にどうぞという形です。
その他ツールの設定
-
.gitignore
... gitignore のテンプレートをそのまま使わせてもらってます(gitignore/Python.gitignore at main · github/gitignore) -
bandit.yaml
... テスト用のファイルに書かれているものについては除外 -
mypy.ini
... strict に -
noxfile.py
... pytest, ruff lint, lizard, sphinx-build など -
pytest.ini
... メインのものとしてはpytest-cov
の coverage が 80 以下だと FAIL するように -
ruff.toml
... ルール設定をめちゃくちゃ厳しくしている
最後に
完全に自己満かもしれないですが、uv
を活用した Python プロジェクトがいい感じにできた気がします。今回紹介したテンプレートで導入したツール以外にも、これは便利なものだよ!というのがあれば導入したいのでぜひご教示いただけると幸いです。
また、それぞれのツールちゃんと活用するだけでも記事が書けてしまうくらい奥深いので、今後はその辺含めてしっかり見ていけたらと思います。
参考
- Modern Good Practices for Python Development · Field Notes
- Rules | Ruff
- Command-line usage — Nox 2025.2.9 documentation
付録として
このテンプレートを作ったときの環境は下記のとおりです。
- MacBook Air M1 (15.3.1)
- Docker version 27.5.1, build 9f9e405
- uv 0.6.0
今回作成したテンプレートでは簡単な ChatGPT に書かせた簡単な TODO アプリをサンプルプロジェクトとして
実装しています。
TODO アプリの動作例
❯ uv run src/uv_python_project_template/main.py
Hello
Todo Application Menu:
1. Add Task
2. List Tasks
3. Mark Task as Complete
4. Remove Task
5. Exit
Enter your choice: 1
Enter the task: test-task
Enter the task description: これはテスト
Todo Application Menu:
1. Add Task
2. List Tasks
3. Mark Task as Complete
4. Remove Task
5. Exit
Enter your choice: 2
=================
1(). test-task
=================
Todo Application Menu:
1. Add Task
2. List Tasks
3. Mark Task as Complete
4. Remove Task
5. Exit
Enter your choice: 3
Enter the task ID to mark as complete: 1
Completed: 1
Task 1 marked as complete.
Todo Application Menu:
1. Add Task
2. List Tasks
3. Mark Task as Complete
4. Remove Task
5. Exit
Enter your choice: 2
=================
1(Completed!). test-task
=================
Todo Application Menu:
1. Add Task
2. List Tasks
3. Mark Task as Complete
4. Remove Task
5. Exit
Enter your choice: 4
Enter the task ID to remove: 1
Task 1 removed.
Todo Application Menu:
1. Add Task
2. List Tasks
3. Mark Task as Complete
4. Remove Task
5. Exit
Enter your choice: 2
No tasks found.
Todo Application Menu:
1. Add Task
2. List Tasks
3. Mark Task as Complete
4. Remove Task
5. Exit
Enter your choice: 5
Exiting the Todo Application.
Discussion