"uv"ってなに
UltraVioletのことではありません(やかましい)。Python のパッケージマネージャであり、 pip や poetry の代替 として開発されている高速なツールです。
以下の特徴があります:
- Rust 製で高速
- pip, venv, setuptools, wheel を統合的に扱える
- 仮想環境の作成・依存関係の解決が爆速
公式ドキュメントは以下です。ここでもこのドキュメントに沿って基本的な使い方を抑えます。
インストール
Linux・macOSの場合
curl -LsSf https://astral.sh/uv/install.sh | sh
筆者の場合、パスが通らなかったので、以下コマンドによりパスを通しました。
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Windowsの場合
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
インストールの確認
バージョン確認のコマンドを入力して、通常レスポンスが返ってこればインストールに成功しています。
uv version
>> uv 0.6.17
仮想環境構築
プロジェクトの作成
下記コマンドを実行すると、
uv init test
ディレクトリ名がtestとなる、プロジェクトディレクトリが作成され、Pythonを利用する開発に必要なファイルが一式用意されていることが分かります。
.python-versionについて
pythonのバージョンが記載されるファイルです。testディレクトリに移動して、下記コマンドを実行すると、Pythonのバージョンが記録されていることが分かります。筆者のローカル環境にインストールされているPythonのバージョンが3.12であるため、デフォルトでは、自動的にデフォルト環境に合わせられることが分かります。
cat .python-version
>> 3.12
pyproject.tomlについて
作成したPythonプロジェクトのメタデータが記載されるファイルになります。後に記載しますが、ライブラリのインストールや削除によって、このファイルも自動的に書き換わります。
[project]
name = "test"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []
依存関係のインストール
requestライブラリをインストールしてみます
uv add requests
すると、testディレクトリ配下に.venvディレクトリとuv.lockファイルが出現します。
.venvディレクトリ
このディレクトリに、作成したプロジェクトで利用する依存関係が入れられます。
uv.lock
プロジェクトの大まかな要件を指定するために使用される pyproject.toml とは異なり、このファイルには、プロジェクト環境にインストールされる解決済みの正確なバージョンが含まれます。このファイルはマニュアルで編集してはいけないようです。
version = 1
revision = 2
requires-python = ">=3.12"
[[package]]
name = "certifi"
version = "2025.4.26"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload_time = "2025-04-26T02:12:29.51Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload_time = "2025-04-26T02:12:27.662Z" },
]
~~~~~~~~~~~~
~~~~(中略)~~~~
~~~~~~~~~~~~
[[package]]
name = "requests"
version = "2.32.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "charset-normalizer" },
{ name = "idna" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload_time = "2024-05-29T15:37:49.536Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload_time = "2024-05-29T15:37:47.027Z" },
]
[[package]]
name = "test"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "requests" },
]
[package.metadata]
requires-dist = [{ name = "requests", specifier = ">=2.32.3" }]
[[package]]
name = "urllib3"
version = "2.4.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload_time = "2025-04-10T15:23:39.232Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload_time = "2025-04-10T15:23:37.377Z" },
]
※ project.tomlの依存関係も更新されています。
[project]
name = "test"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"requests>=2.32.3",
]
ライブラリの削除および更新
// 削除
uv remove requests
// 更新
uv lock --upgrade-package requests
スクリプトの実行
flaskを仮想環境にインストール(uv add flask)したのち、以下のスクリプトを実行することにします。
import flask
def main():
print("Hello from test!")
if __name__ == "__main__":
main()
uv run main.py
>> Hello from test!
flaskの依存関係が解決されており、正常に実行できたことが分かります。
Pythonのバージョン管理について
結論から申し上げると、pythonのバージョン管理が可能で、すでにあるpythonも新規のpythonも簡単に利用可能です。
まず、利用できるPythonランタイムの一覧を表示しましょう。以下のコマンドを実行すると、
uv python list
uvで利用できる、Pythonランタイムがすべて表示されます。と記載のあるものは、現在のローカル環境にはないが、インストールすれば利用できるもの、パスの記載のあるものは、すでに存在していて、パスを指定すればそのまま利用できるものになります。
cpython-3.14.0a6-linux-x86_64-gnu <download available>
cpython-3.14.0a6+freethreaded-linux-x86_64-gnu <download available>
cpython-3.13.3-linux-x86_64-gnu <download available>
cpython-3.13.3+freethreaded-linux-x86_64-gnu <download available>
cpython-3.12.10-linux-x86_64-gnu <download available>
cpython-3.12.9-linux-x86_64-gnu miniconda3/bin/python3.12
cpython-3.12.9-linux-x86_64-gnu miniconda3/bin/python3 -> python3.12
cpython-3.12.9-linux-x86_64-gnu miniconda3/bin/python -> python3.12
cpython-3.12.3-linux-x86_64-gnu /usr/bin/python3.12
cpython-3.12.3-linux-x86_64-gnu /usr/bin/python3 -> python3.12
cpython-3.11.12-linux-x86_64-gnu .local/share/uv/python/cpython-3.11.12-linux-x86_64-gnu/bin/python3.11
cpython-3.10.17-linux-x86_64-gnu <download available>
cpython-3.9.22-linux-x86_64-gnu <download available>
cpython-3.8.20-linux-x86_64-gnu <download available>
cpython-3.7.9-linux-x86_64-gnu <download available>
pypy-3.11.11-linux-x86_64-gnu <download available>
pypy-3.10.16-linux-x86_64-gnu <download available>
pypy-3.9.19-linux-x86_64-gnu <download available>
pypy-3.8.16-linux-x86_64-gnu <download available>
pypy-3.7.13-linux-x86_64-gnu <download available>
例えば、cpython-3.14.0a6-linux-x86_64-gnuを利用した仮想環境を構築したい場合、以下のコマンドを実行すると、指定のPythonランタイムがダウンロードされます。
uv init --python cpython-3.14.0a6-linux-x86_64-gnu test1
>> Initialized project `test1` at `/home/pepper/test1`
以下のように、python3.14を利用して、仮想環境が構築できていることが分かります。
cat .python-version
>>3.14
一方、miniconda3/bin/python3.12というように、パスで指定すると、そのpythonランタイムがそのまま利用されます。
uv init --python miniconda3/bin/python3.12 test2
>> Initialized project `test2` at `/home/pepper/test2`
以下のように、python3.12を利用して、仮想環境が構築できていることが分かります。
cat .python-version
>>3.12