門脇
はじめに
どのようなプログラミング言語においても、仮想環境の構築やパッケージ管理は重要です。本記事でいう
Pythonの場合、使用するサードパーティライブラリがそれほど多くないケースではpipやvenvだけで十分ですが、プロジェクトが大きくなるとパッケージ同士の依存関係が複雑になったり、インストールに時間がかかったりします。このような問題を解決するため、Pythonにはさまざまなパッケージ管理ツールがあります。
まずはPythonでよく使用されるパッケージ管理ツールと、uvの特徴について簡単に説明します。
パッケージ管理ツール
Pythonでよく使用されるパッケージ管理、仮想環境管理ツールには以下があります。
ツール名 | 役割 |
---|---|
pyenv | Pythonのバージョン管理 |
venv | 仮想環境の管理 |
pip | パッケージの管理 |
pipenv | パッケージ・ |
Conda | パッケージ・ |
Poetry | パッケージ・ |
Rye | Pythonバージョン・ |
それぞれのツールに関する詳しい説明は本記事では行いません。詳しく知りたい方は、ツール名のリンクから公式ドキュメント等を参照してみてください。
上記の表に挙げたツール群にはそれぞれに特徴があります。pyenv、venv、pipのように単一機能に特化したものから、Condaのようにデータサイエンスや機械学習プロジェクトで使用される複雑なパッケージの依存関係や環境管理をサポートするツール、PoetryのようにPythonパッケージインデックス
uvとは
uvは2024年の2月中旬に発表されたばかりの新しいパッケージ管理ツールです。Rustで書かれており、ここ最近で飛躍的に使用されるようになったRust製のPythonリンター&フォーマッター
Rustのパッケージマネージャである
uvのインストールと使い方
実際にuvをインストールして使ってみましょう。uvの開発はかなり活発に行われています。執筆時点でも1週間もしないうちにマイナーバージョンが5つも上がってしまうほどでしたので、この記事が公開される頃にはさらにバージョンが上がっていることが予想されます。
執筆時点での最終バージョンは
インストール方法
uvはPythonと依存関係がないため、Python自体とは別にインストールできます。したがって、システムに複数のPythonバージョンが存在していても、それぞれにインストールする必要はありません。
もちろん、pipコマンドで手っ取り早くインストールすることもできます。ひとまず試してみたい方には以下がおすすめです。
$ pip install uv Collecting uv |████████████████████████████████| 20.3 MB 422 kB/s Installing collected packages: uv Successfully installed uv-0.1.21
pipを使用せず、LinuxやmacOSのシステム全体で使用したい場合は以下のように行います。
$ curl -LsSf https://astral.sh/uv/install.sh | sh installing to /Users/kadowaki/.cargo/bin uv everything's installed! To add $HOME/.cargo/bin to your PATH, either restart your shell or run: source $HOME/.cargo/env
システム全体にインストールした場合は、パスを通す必要があります。出力メッセージに従いsource $HOME/
を実行して、環境変数
なお、Windowsなどその他のインストール方法について知りたい方は、以下のREADMEに記載がありますので、参照してみてください。
仮想環境の作成
次に仮想環境を作成します。ここでは、速度の違いを確認するためにtime
コマンドを使用して実行時間を計測してみます。
最初にPython標準のvenvで仮想環境を作成します。今回はPythonは3.
$ time python3.12 -m venv std-env python3.12 -m venv std-env 3.56s user 0.63s system 83% cpu 5.068 total
仮想環境の作成に約5秒かかっています。
続いてuvで仮想環境を作成します。uvで仮想環境を作成する場合は、以下のように、uv
コマンドにvenv
引数を指定して実行します。デフォルトではuvコマンドを実行したディレクトリ内に
$ time uv venv Using Python 3.12.2 interpreter at: /usr/local/bin/python3.12 Creating virtualenv at: .venv Activate with: source .venv/bin/activate uv venv 0.01s user 0.01s system 88% cpu 0.023 total
なんと、uv venv
の実行は0.
デフォルトの.venvディレクトリではなく、ディレクトリ名を指定したい場合はuv venv {ディレクトリ名}
のように実行します。また、--python {Pythonのインストールパス}
のように、オプションで仮想環境のPythonのバージョンを指定できます。
以下の例では、Python 3.
$ uv venv uvenv-test --python /usr/local/bin/python3.11 Using Python 3.11.2 interpreter at: /usr/local/opt/python@3.11/bin/python3.11 Creating virtualenv at: uvenv-test Activate with: source uvenv-test/bin/activate
仮想環境のアクティベート
LinuxやmacOS環境で仮想環境をアクティベートする方法はPython標準のvenvと同じです。仮想環境ディレクトリにあるbin/
をsource
コマンドで実行します。アクティベートされると、Python標準のvenvと同じくプロンプトに仮想環境のフォルダ名が表示されます。仮想環境ディレクトリを指定せず、デフォルトの.venvディレクトリで作成した場合は、上位のフォルダ名が表示されます。
$ source .venv/bin/activate (work_dir) $ # プロンプトに上位のフォルダ名が表示されている
パッケージインストールの前に、アクティベートされた環境について少し確認してみます。Pythonの実行パスやバージョンが以下のように設定されています。
- 作成した仮想環境ディレクトリ
(例: .venv) にあるPythonが使用されている - 仮想環境を作成する際に使用したPythonと同じバージョンで作成されている
# 作成した仮想環境ディレクトリ(.venv)にあるPythonが使用されていることを確認 (work_dir) $ which python /Users/kadowaki/work_dir/.venv/bin/python # pythonコマンドを使用してバージョンを確認 (work_dir) $ python --version Python 3.12.2
続いて、標準でインストールされるパッケージを確認します。uv
コマンドにpip list
を引数として実行しますpip list
だけを実行すると、システム全体にインストールされているパッケージのリストが表示されますので注意してください)。
(work_dir) $ uv pip list (work_dir) $
uv pip list
コマンドの結果は何も出力されずに終了するはずです。Python標準のvenvでは以下のようにデフォルトでpipがインストールされますが、uvが作成する仮想環境にはpipやsetuptoolsはインストールされません。つまり、uvが提供するpipによってパッケージ管理が行われます。この点も標準とは少し異なりますが、仮想環境ごとにpip自体のバージョンを上げる手間を省くことができるのはありがたい仕様です。
# Python標準のvenvで標準インストールされているパッケージ $ pip list Package Version ------- ------- pip 24.0
パッケージのインストール
それでは、パッケージのインストールを行ってみましょう。今回はtime
コマンドを使用して時間を計測してみます。また、--no-cache
オプションを使用してキャッシュがパフォーマンスに影響しないようにして比較します。
まずは先ほど作成した、Python標準のvenvで作った仮想環境上
(std-env) $ time pip install pandas --no-cache Collecting pandas Downloading pandas-2.2.1-cp312-cp312-macosx_10_9_x86_64.whl.metadata (19 kB) (省略) Installing collected packages: pytz, tzdata, six, numpy, python-dateutil, pandas Successfully installed numpy-1.26.4 pandas-2.2.1 python-dateutil-2.9.0.post0 pytz-2024.1 six-1.16.0 tzdata-2024.1 pip install pandas --no-cache 10.94s user 2.90s system 75% cpu 18.267 total
インストールに約18秒かかりました。続いて、uvの仮想環境にインストールしてみます。uv pip install {パッケージ名}
のように、uvコマンドに続けてpip installを実行します。
(work_dir) $ time uv pip install pandas --no-cache Resolved 6 packages in 579ms Downloaded 6 packages in 1.87s Installed 6 packages in 80ms + numpy==1.26.4 + pandas==2.2.1 + python-dateutil==2.9.0.post0 + pytz==2024.1 + six==1.16.0 + tzdata==2024.1 uv pip install pandas --no-cache 0.94s user 1.62s system 82% cpu 3.090 total
なんとpandasのインストールが約3秒で終了しました。あまりにも爆速すぎて唖然とするほどですが、この速度で信頼できる仮想環境を構築できるということだけで、新たなパッケージ管理ツールの選択肢の1つになり得ると思ってしまいます。
pipとuv pipの違い
Python標準のpipとuv pip
の比較を簡単にまとめると以下のようになります。
uv pip
はPython標準のpipと比較して数倍から数十倍速い- pipが持つ機能のすべてを網羅しているわけではないが、必要な機能は備わっている
- パッケージ間の依存関係解決についてはPython標準のpipと動作が異なる場合がある
それぞれについて簡単に説明します。
「1.」uv pip
の速度については、Rustの恩恵によりベンチマークでは10〜100倍速いと謳っています。筆者が試した環境でも、nightlyのTensorFlowのように比較的重めのパッケージインストールを試してみても、2倍以上uvが速い結果になりました。
「2.」uv pip
コマンドがPython標準のpipと同様に使用できます。
- uv pip install
- uv pip install -r requirements.
txt
- uv pip install -r requirements.
- uv pip uninstall
- uv pip list
- uv pip freeze
また、uvでは以下のような、pyproject.
- uv pip install -r pyporject.
toml - uv pip sync requirements.
txt
「3.」
ただし、以下の条件を満たす依存関係は非ステーブルでもインストールされます。
- 依存関係のあるパッケージについて、ベータ版などのプレリリースバージョンが直接指定されている場合
- 公開されているパッケージのバージョンが全てプレリリースバージョンである場合
試しにmatplotlibのnightlyパッケージをインストールしてみたところ、以下のようにmatplotlib自体のバージョンも異なるケースに遭遇しました。
プレリリースバージョンを積極的に利用する機会は少ないと思いますが、Python標準のpipでは依存関係のあるパッケージでプレリリースバージョンが自動的にインストールされるケースもあるため、少し注意が必要です。
Ryeとuv
最初に示した
詳細について知りたい方は以下のブログを確認してみてください。1つめのブログはuvに関する最初のブログ記事でもあり、機能面の内容についても参考になります。
2つめのブログにも記載がありますが、Ryeは2023年に個人でスタートしたプロジェクトで、Pythonのパッケージ管理ツールがどうあるべきかを試したり、解決策を探ったりするにはとても便利なツールだったものの、さまざまなツールを寄せ集めて作成しているため脆弱さもあり、個人のサイドプロジェクトとして進めていくことの難しさもあったようです。
今後はRyeをAstral社の管理下に置きつつも、Pythonツールのテストベッドとしてさらに探求を続けるとのことで、その知見を活かして、uvはより高レベルなツールへと発展していくことを目指しているとのことです。
まとめ
uvはpipやvenvの代替として