uvを1年間使ってみた: 長所・短所と移行時に考えるべき点
(bitecode.dev)- 複数のクライアント環境で1年間使ってみた uv は、Pythonプロジェクトの開始と依存関係管理を大幅に簡素化し、使える環境ならまず試してみる価値がある
- 既存の pip/venvワークフロー をほぼ維持しつつ、より高速かつ安定して動作するため、移行コストは比較的低い
- Pythonのインストール、仮想環境、ロックファイル、実行、ビルド、一時的なツール実行を1つのツールにまとめ、プロジェクト実験のコスト を大きく下げる
- 一方で、レガシーな依存関係の解決失敗、
python-build-standaloneのサポート範囲、20GB超まで膨らみうるキャッシュ、企業のセキュリティポリシー、CLIの壁は現実的な制約となる - Pythonの仕事を続けるなら、uvを使うとしても pip と venv は知っておくべきであり、uvが許可されない、または適さない環境に備える必要がある
Pythonプロジェクトが難しくなる出発点
- Pythonで最も大きな問題の根っこは、Python自体を用意し、新しいプロジェクトを始める ブートストラップ にある
- その後に直面するパッケージング問題の多くも、依存関係のインストールやパッケージのビルドそのものより、初期のPythonインストールやプロジェクト設定に起因している
- Pythonのインストール方法はOSごとに異なり、デフォルトや落とし穴もばらばら
- 初学者向きの言語であるにもかかわらず、Pythonをインストールするには事前に知っておくべき知識が多い
- Pythonは、学生、データサイエンティスト、AI開発者、Web開発者、システム管理者、生物学者、地理学者、プラグイン開発者など、非常に多様な層に使われている
- 会社支給のWindowsマシン、個人のDebianノートPC、大学、行政機関、スタートアップ、軍、研究所、大企業などで実行環境の差が大きく、1つのチュートリアルですべてをカバーするのは難しい
PATH、PYTHONPATH、複数Pythonバージョンの共存、Linuxの選択パッケージ、システム依存としてのPython、コンパイル拡張の人気などが複雑さを増している- 良いPythonプロジェクト管理ツールは、次の条件を満たすべき
- Pythonのブートストラップと独立して動作すること
- プラットフォームや状況をまたいでPythonのインストールと実行を統一すること
pipやvenvのような基本ツールとの橋渡しになること- 強力な 依存関係リゾルバ を備えていること
- 単純なインストールは簡単に処理し、別OSでロックされた依存関係をインストールするような複雑な作業にも対応できること
- インストールと利用が容易で、スタックの重要部分を任せられるだけの信頼性があること
uvのブートストラップ方式
- uv はPythonとは完全に独立してインストール・更新され、uvのインストールとPythonのインストールは互いに影響しない
- Pythonのブートストラップ問題、
PATH問題、import問題がuv自体に影響しない - インストール先をシステムにするか仮想環境にするか、新しいキーワードや廃止予定がuvにどう影響するか、といった混乱が減る
- uvはまず
pipとvenvのインターフェースを提供し、既存のプロジェクト、ツール、考え方と併用できるようにした- これは既存コミュニティとレガシーコードを考慮した選択
- ユーザーは
uv run、uv add、uvxを覚えなくても、既存のpip・venvワークフローのように使える - 基本作業で得られる速度と信頼性だけでも移行する理由になる
- Pythonインストール機能も提供する
- すべてのOSで統一された方法でインストールできる
- 管理者権限が不要
- システムPythonと独立して動作する
- 複数バージョンをインストールしても衝突しない
- 同じ標準ライブラリを提供し、
tkinterも含まれる - Pypy、No-GIL、TCO版も含む
- shim、コンパイル、不合理なデフォルトなしで動作する
Pythonインストール体験と python-build-standalone
uv python install pypy3.8の例では Python 3.8.16 を2.71秒でインストールできる- 同じ方法でMacやWindowsでも実行できる
- Tcl、OpenSSL、Gzip関連の不足パッケージ、他のPythonインストール元との競合、OSごとに異なる作法、不足コマンド、誤設定された
PATHは現れない - uvのPythonインストールは python-build-standalone を活用しており、Astralはこのプロジェクトを引き継いで改善している
- Astralはこの利点をcPython本流プロジェクトへ還元しようとしており、周辺のオープンソースプロジェクトにも貢献してきた
プロジェクト管理機能
uv initはデフォルトで.venv、pyproject.toml、Python用.gitignoreを含むgitリポジトリ、README.md、hello.pyを作成する- ルート依存関係は
pyproject.tomlに宣言するか、uv addで追加できる uv removeはリポジトリを正しく整理するuv lock --upgrade-package <package>==<version>は、パッケージを1バージョンずつ慎重にアップグレードできるようにするuv buildはプロジェクトから.whlパッケージを作るが、uvはプロジェクトがビルド可能であることを必須にはしていないuv runは仮想環境が有効化されていなくても、その中でコマンドを実行する- ユーザーは仮想環境の存在や有効化という概念を知らなくてもよい
- これらのコマンドはロックファイルを自動かつ透過的に更新する
- uvは高速なので、更新が起きていることをほとんど感じない
- ユーザーはロックファイルが何かを知らなくてもよい
- ロックファイルはクロスプラットフォーム なので、Windowsで開発してLinuxへデプロイできる
性能、安定性、エラーメッセージ
- uvの性能は、依存関係のインストールやプロジェクト実験にかかるコストを下げる
- 素早くやり直せるので、複数の試行を気軽に繰り返せる
pyenv、pipenv、poetryのようなツールは、環境によってはスタックトレースを出して壊れることがあったが、uvは非常に堅牢に動作した- Astralの品質面では、特に3つが目立つ
- バグ修正が速く、フィードバックやレポートへの反応がよい
- テスト文化が強く、依存関係解決テストスイート を別パッケージとして提供している
- エラーメッセージが非常に優れている
uv add httpie==2の例では、httpie==2.0.0がrequests>=2.22.0に依存している一方で、プロジェクトがrequests==1に依存しているため要件を満たせないことを段階的に示してくれる- 依存関係解決のエラーメッセージは pubgrub の影響もあるが、uv全体のエラーメッセージも同じ方向性に沿っている
- 教育現場でuvを使ったとき、学生たちは大きな介入なしに生産的に使え、他のツールではこうした経験はなかった
- 新規の専門的なプロジェクトではuvの利点を簡単に得られたが、レガシープロジェクトでは障害要因が現れることがある
uvxと新しい使い方
- uvはPythonと依存関係の準備・分離を、強力で高速な基本要素として提供する
- 以前はPythonと依存関係の準備は遅く壊れやすい制約だったが、uvではワークフローを調整する 機能 のように扱える
uv run --with jupyter jupyter notebookは現在のプロジェクトでJupyterを実行するが、Jupyterとその依存関係をプロジェクトに追加しないuvx --with pendulum -p 3.13t pythonは、新しいPython No-GILビルドをダウンロード・インストールし、一時的な仮想環境を作成し、pendulumをインストールしたうえでPythonシェルを起動するuvxはPython向けのnpxのようなツールで、pipxをきちんと作り直したものと見ることもできる- インライン依存関係 のサポートは、小さなPythonスクリプトで依存関係を使う方法を変える
- 以前は小さなスクリプトで依存関係を避けるか、面倒な回避策を使う必要があった
- 今では高速で透過的かつ自己説明的な方法で依存関係を使える
- こうした機能は強制されず、ユーザーが必要になったときに見つけて導入できる
uvが失敗したり不便だったりする点
- uvは実際のパッケージング問題そのものを代わりに解決することはできない
- 誤ったバージョンマーカー、wheelの欠如、名前衝突といった問題はuvの制御外
- こうした問題はPyPI上のデータ品質に内在している
- uvでパッケージング問題が減る理由は、他の部分を正しく処理しているから
- より厳格な依存関係リゾルバのため、古い
pipの緩い解決に依存していたレガシープロジェクトの仮想環境は壊れることがある- Python 3への移行がようやく終わった15年物のコードベースで、整理されていない
pip freezeの内容に依存していたケースでは、uvは動かなかった
- Python 3への移行がようやく終わった15年物のコードベースで、整理されていない
- uv内蔵のPythonインストールは
python-build-standaloneでビルドされたバージョンに制限される- python.orgのインストーラ、deadsnake、pyenvなら、より多くのPythonバージョンをインストールできる
- 特定のPythonバージョンが必須の古いプロジェクトでは問題になりうる
- uvは外部でインストールしたPythonとも問題なく動くので、完全な阻害要因ではない
python-build-standaloneの実行ファイルはやや遅いことがあるpyperformanceベースでは、uvの3.10はUbuntuのPythonより3%遅かった- ハードウェア最適化してコンパイルしたPythonを使いたい場合もある
- キャッシュ容量も欠点になりうる
- 1年使った後、uvのキャッシュはディスク上で 20GB超 を占めていた
uv cache cleanで削除できるが、その場合は速度面の利点を失うpipと違ってパッケージをハードリンクして1回分しか容量を使わないため、従来の複数仮想環境全体より少ない可能性もある
$UV_PYTHONがデフォルト版を与えるのではなくPythonバージョンを強制してしまう不便さがあり、関連Issueは対応中- uvはオープンソースだが、商用企業Astralのプロダクトでもある
- Astralはまだ収益化しておらず、商用製品も公開していない
- スタックの重要部分を任せる前に慎重であるべきだという意見もある
- 逆に、uvへ移行するコストもuvから離脱するコストも低いという見方もある
- 最大の制約は企業導入
- セキュリティが厳しく閉じた大企業環境では、新しい依存関係のインストール自体が非常に難しい
- ITセキュリティ部門がマシン上でできることを統制している場合、uvのインストールが許可されないこともある
- 安定版に達し、さまざまな要件を満たすまでは、企業環境での制約は大きい
- CLIも障壁
- コマンドラインに慣れていないPythonユーザー、特にWindowsユーザーは少なくない
- AnacondaにGUIがある理由の1つもここにある
- 完全な初心者にCLIツールを求めるのは参入障壁になる
uvxとuv tool installは、pipxのようにツールをプロジェクト外へインストールする方向に導くyt-dlp、httpieのような独立ツールには向いているmypyのようにPythonバージョンやライブラリ文法に敏感な開発ツールは、プロジェクトと異なるPythonバージョンにインストールされて問題を起こすことがある
uvを避けるべきとき
- uvを使わないほうがよい状況は5つある
- uvの依存関係解決では動かないレガシープロジェクトがあり、移行のために整理する余力がない、またはその意思がない
- 企業環境がuvの利用を許可していない
- まだ安定版ではないこと、Astralの商用製品が出ていないこと、Rustコントリビューター層が小さいことなどの理由で信頼できない
- uvが提供していない特定のPythonバージョンが必要で、外部インストールのPythonと併用したくない
- チームにとってCLIが大きすぎる障害になっている
- 信頼性の問題と特定Pythonバージョンの問題は、技術的な阻害というより選択の問題に近い
- 企業環境の制限については、ユーザー側でできることは多くない
- 実質的に検討すべき核心は レガシー依存関係 とCLIの壁
- 助言はシンプル
- まず常にuvを試す
- 動かなければ従来の方法に戻るか、回避策を探す
- CLIが問題なら、Pythonの準備には python.org のインストーラを使い、uvをラップするIDEプラグインを提案できる
- プログラミングできる人なら、uvを使うために必要なコマンドラインの基礎を学べる可能性が高い
今後の位置づけ
- 企業環境で使うにはv1までに埋めるべきギャップがあり、企業では頻繁に更新しにくいため安定版が重要
- pex/shivの代替になりうるバンドリング機能や、ビルドバックエンドが追加される可能性があると予想される
- アプリケーション向けインストーラ生成機能は論理的な帰結にも見えるが、署名だけでも適切に扱うのが難しく、はるかに複雑
- taskサポートが整理されれば、個人的な必要には十分な機能を備えた状態になる
- Pythonが仕事なら、
pipとvenvの使い方は依然として学ぶべき- いつかuvを使えない状況に出会うかもしれないため
- 結論としてuvはコストが低く利点が大きいため、使える環境ではまず試してみる価値のある Pareto解 である
まだコメントはありません。