pipx から uv tool へ移行する — Python の CLI ツール管理

公開日:
目次

複数のプロジェクトを行き来していると、ruffblack のようにグローバルに置いておきたいCLIツールが少しずつ増えてきます。これまではpipxで揃えていましたが、uvに移ったタイミングで uv tool の方に流しました。起動が速くPythonのバージョンも自動で見繕ってくれるので、戻る理由がなくなりました。

uv tool が担う役割

uv tool は、CLI として使う Python 製のツール(lint・整形・HTTPクライアントなど)を、プロジェクト本体とは独立した環境にインストールする機能です。pipx と同じ役回りで、各ツールに専用の仮想環境を割り当てて互いに干渉させない設計になっています。

uv本体に組み込まれているのが大きな違いで、追加のインストールは要りません。前回書いた uv python install でPython本体を持っているなら、その上に直接ツールを乗せられます[1]

インストールと実行

ツールを常駐させたいか、一度だけ走らせたいかで入口が2つあります。

永続的に置く uv tool install

uv tool install ruff
uv tool install httpie
uv tool install black

PATHにエイリアスが作られ、シェルを開き直さなくても次から呼べます。インストール先は ~/.local/share/uv/tools/ 以下で、ツールごとに専用の仮想環境が作られます。

一度だけ動かす uvx

uvx cowsay "hello"

uvxuv tool run の別名です。その場でツールを取りに行って実行し、終わったら使い終わった一時環境を片付けます。CI上のワンショット実行や、試しに触ってみたいだけのツールに向いています。

管理コマンド

入れたあとは uv tool の傘下にコマンドが揃っています。

uv tool list             # インストール済みを一覧
uv tool upgrade ruff     # 個別アップグレード
uv tool upgrade --all    # 全部まとめて
uv tool uninstall ruff   # 削除
uv tool dir              # 格納ディレクトリを表示

PATHが通っていない環境では uv tool update-shell を実行すると ~/.zshrc などに必要な行を追記してくれます。手動で書く手間がないのは pipx ensurepath と同じ感覚です。

pipx からの移行

既に pipx で揃えた環境がある場合、pipx と uv tool を併用しても干渉はしません。格納先のディレクトリが分かれているので両方共存できます。ただし同じツールを両方で入れていると which ruff がどちらを指すかPATHの優先順で決まるので、移行のタイミングで pipx 側を片付けるのが素直です。

# pipx 側を整理する例
pipx list
pipx uninstall ruff
pipx uninstall black

その上で uv tool install で同じ一覧を再構築します。私はツール名のリストをメモに残しておいて、Macを新調したタイミングで xargs uv tool install で一気に流す運用にしています。

ハマったところ

ツールが依存する追加パッケージを入れるときは --with を使います。例えばIPythonにJupyter拡張を抱かせたい場合:

uv tool install ipython --with jupyter

--with を覚える前は「グローバルな追加パッケージはどこに入れるんだろう」と迷いました。各ツールが独立した仮想環境を持つので、依存も個別に管理する作りです。

もう1つは、Python本体のバージョンを明示したくなる場面です。デフォルトでは uv が自動で選びますが、特定のツールだけ古いPythonで動かしたいときは --python を渡します。

uv tool install --python 3.10 some-legacy-tool

pipx を残す判断

uv tool に寄せても困らない場面が大半でした。それでも pipx を残す価値が出るのは、pipx 専用の挙動(pipx run --spec git+... の細かい指定など)に依存している自動化スクリプトが既にある場合や、チームの共通環境構築スクリプトが pipx 前提で書かれている場合です。

新しく始めるなら uv tool 一択、既存資産があれば段階的移行が現実的です。詳しい挙動はTools のドキュメント[2]に整理されています。uvx --from package command のように「パッケージ名と実行コマンドが違うとき」の指定方法もあるので、ユースケースに当たったらまずここを見ると早いです。

脚注
  1. uv | Astral ↩︎

  2. Tools - uv ↩︎