Fragments of verbose memory

冗長な記憶の断片 - Web技術のメモをほぼ毎日更新(準備中)

Jan 5, 2025 - 日記

uv のサブコマンドを分類して完全に理解した

最近Python のプロジェクト管理ツールである uv を使い始めました。

そのサブコマンドは一見シンプルに見えますが、似たような機能に見えるコマンドがあるため 「どのコマンドを使えばいいの?」と戸惑うことがあります。 これは、 uv のサブコマンドに「低レベルの機能」と「高レベルのラッパー」が混在しているためです。

この記事では、 uv のサブコマンドを低レベルの機能と高レベルのラッパーに分類し、それぞれの役割や使いどころを整理してみます。特に、普段遣いで便利な高レベルのラッパーに注目し、効率的な使い方を解説します。

uv のサブコマンドを分類する

uv のサブコマンドは、以下のように分類できます。

低レベルの機能

これらのコマンドは特定のタスクを直接実行するための基本的な操作を提供します。

  • uv pip: パッケージのインストールやアンインストールを行う。
  • uv venv: 仮想環境の作成や管理を行う。
  • uv python: Python のバージョン管理やインストールを行う。
  • uv cache: キャッシュの管理を行う。
  • uv self: uv 自身のアップデートや管理を行う。

高レベルのラッパー

これらのコマンドは、低レベルの機能を組み合わせて、ユーザーが簡単に操作できるように設計されています。

  • uv add: パッケージをインストールし、pyproject.toml に追加。
  • uv remove: パッケージをアンインストールし、pyproject.toml から削除。
  • uv sync: pyproject.toml に基づいて依存関係をインストールし、環境を同期。
  • uv lock: 依存関係のバージョンを固定するロックファイルを生成または更新。
  • uv run: 仮想環境を意識せずにスクリプトやコマンドを実行。
  • uv tool: プロジェクトで使用するツールの管理。

高レベルのラッパーを使うと便利な理由

低レベルのコマンドを使えば、細かな操作を自由に行うことができます。しかし、普段遣いでは高レベルのラッパーを使う方が便利です。その理由を具体例とともに見ていきましょう。

例 1: パッケージのインストール

低レベルの方法:

uv pip install requests
# 依存関係を手動で pyproject.toml に記載

高レベルのラッパー:

uv add requests

ポイント: uv add を使うと、パッケージのインストールと pyproject.toml の更新が一度に行えます。

例 2: 依存関係の同期

低レベルの方法:

uv pip install -r requirements.txt

高レベルのラッパー:

uv sync

ポイント: uv syncpyproject.toml に基づいて環境全体を同期するので、手動で requirements.txt を扱う必要がありません。

例 3: 仮想環境の初期化

低レベルの方法:

uv venv create
# 必要ならば手動で環境を有効化 または
python -m venv .venv

高レベルのラッパー:

uv init

ポイント: uv init は仮想環境の作成と初期化を一度に行い、プロジェクトをすぐに開始できる状態にします。


uv と pyenv の関係

uv は Python のバージョン管理に関する機能も備えていますが、 pyenv のような専用ツールと比較した場合、どのような関係になるのでしょうか?以下にその特徴を整理します。

uv の Python バージョン管理機能

  • uv python pin でプロジェクトに特定の Python バージョンを固定可能。
  • uv python install で特定の Python バージョンをインストール可能。
  • uv python list で利用可能な Python バージョンを一覧表示。

メリット:

  • プロジェクトごとにバージョンを固定できるため、チーム開発でのバージョンの不一致を防ぎやすい。
  • pyproject.toml にバージョン情報を記録することで、他の依存関係と統一的に管理可能。

制限:

  • Python のインストールや管理のための操作は基本的にローカルに限定されているため、pyenv のようにシステム全体でのバージョン管理が目的ではない。

pyenv の特徴

  • システム全体、ユーザー単位、ディレクトリ単位で Python バージョンを切り替え可能。
  • インストールできる Python バージョンの種類が豊富(公式バージョン、開発中のバージョン、PyPy、Stackless など)。
  • 他のツール(pipenvpoetry など)と組み合わせることで柔軟な運用が可能。

メリット:

  • システム全体での Python バージョンの管理が容易。
  • 複数のプロジェクトで異なるバージョンを使用する場合に便利。

制限:

  • プロジェクトごとの依存関係管理との統合が弱く、別途ツールが必要になることが多い。

uvpyenv を不要にするケース

  • プロジェクトごとに特定の Python バージョンを固定し、チーム全体で同じ設定を共有することが主な目的の場合。
  • Python のインストールやバージョン管理を uv に一任し、プロジェクト管理ツールとしての一貫性を重視する場合。

pyenv が必要なケース

  • システム全体や複数のプロジェクトで異なる Python バージョンを頻繁に切り替える場合。
  • 特定の公式リリース外の Python バージョン(例: PyPy)の利用が必要な場合。
  • 既存の開発環境で pyenv を中心にツールチェーンが構築されている場合。

高レベルラッパーと低レベル機能の関係

以下の表は、低レベルの機能とそれを置き換える高レベルのラッパーをまとめたものです。

低レベルコマンド高レベルラッパー説明
uv pip install パッケージ名uv add パッケージ名パッケージのインストールと設定ファイルの更新を一度に実行。
uv pip uninstall パッケージ名uv remove パッケージ名パッケージのアンインストールと設定ファイルの更新を一度に実行。
uv pip install -r requirements.txtuv syncpyproject.toml に基づき環境を同期。
uv pip freeze > requirements.txtuv lock依存関係のバージョン固定を簡単に実現。
source .venv/bin/activate python script.pyuv run python script.py仮想環境を意識せずにスクリプトを実行。
uv venv createuv initプロジェクトの初期化と仮想環境の作成を一度に実行。
pyenv install バージョンuv python install バージョン特定の Python バージョンをインストール。
pyenv local バージョンuv python pin バージョンプロジェクト単位で Python バージョンを固定。

uv の高レベルラッパーは、Python プロジェクトの管理をシンプルかつ効率的にしてくれる便利な機能です。一方で、低レベルの機能を直接使用することで、より細かな制御も可能です。低レベルの機能を利用したあとに pyproject.toml を手動で更新している様な作業は、高レベルのラッパーの利用で一元化できる可能性があります。用途や目的に応じて高レベルラッパーと低レベル機能を使い分けることで、 uv の真価を最大限に引き出しましょう。

リンク