uv 覚書
Ryeからの移行(Windows)
latest = v0.4.4 時点でのメモ
Ryeをアンインストール
ryeをアンインストール. git bashから実行するとなぜかうまく動作しなかったのでpowershellから実行
# 管理者権限で実行
rye self uninstall
ユーザーディレクトリ下の.rye/config.toml
だけ生き残ってたので手動で削除
uvをインストール
powershellからirm https://astral.sh/uv/install.ps1 | iex
を実行すればよいはずだがエラーになったので調べてみると以下のIssueと同じ状況っぽい
SecurityProtocolを指定して再実行するとインストールされた
# ↓1行を$PROFILEに書いといたほうがいい uv self updateしたときも引っかかるので
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;
irm https://astral.sh/uv/install.ps1 | iex
このIssueにたどり着く前にpipxからインストールを試みたが、その際は某セキュリティソフトに不正なアプリとして検出されてしまった。その際のごちゃごちゃで
- pipxでインストール
- 上記Issueの手順でインストール
- pipxのほうが重複したので
pipx uninstall uv
としたのだが、2の時点ではuvをpowershellから呼び出せたのだが、3でpipx uninstallしたところuvを呼び出せなくなった。
PATH環境変数にuvへのパス(たぶんC:\Users\{User名}\.cargo\bin
)は残っていたが、CARGO_HOMEという環境変数が消えていたのでそちらを手動で追加した(同様にC:\Users\{User名}\.cargo\bin
)
Pythonをinstallする
uv python list
して何もインストールされてない状態(<download available>
になってる状態)でuv python install
してみる
❯ uv python install 3.12
❯ uv python list
cpython-3.12.6-windows-x86_64-none AppData\Roaming\uv\python\cpython-3.12.6-windows-x86_64-none\python.exe
❯ uv run python --version
3.12.6
❯ uv run python -c 'print("hello world")'
hello world
❯ uv run --python 3.12 python --version
Python 3.12.6
❯ uv run --python 3.11 python --version
# 3.11をinstallしてない場合はコマンド実行前にinstallされる
Python 3.11.10
installしたインタプリタはグローバルに呼び出せるわけではない
❯ uv python install 3.12
❯ python --version
# pythonは呼び出されない
Python
A python executable is not made globally available, managed Python versions are only used in uv commands or in active virtual environments.
tool機能
npxだったりpipxだったりな機能のやつ
-
uvx <package_name>
(=uv tool run <package_name>
) すると一時領域にパッケージをインストールしてパッケージを使用できる- 一時的になので
uv tool list
の一覧にはでてこない
- 一時的になので
- 恒久的に使いたい場合は
uv tool install ruff
のようにしてインストールする- install すると
uv tool list
の一覧に表示される
- install すると
- インストールされたパッケージは特定のbinディレクトリに保存されるが、binへのPATHが通ってないとインストール時に警告が出る。
uv tool update-shell
を実行するとPATHを通してくれる。 -
uv tool uninstall
でインストールされたパッケージの削除 -
uvx ruff --version
で最新のruff(例えば0.6.7)を使用した後でuv tool install ruff@0.6.0
など特定のバージョンをインストールするとuvx ruff
も0.6.0を使用するようになる。この状態で特定のバージョンを一時的に実行したければuvx ruff@latest --version
などすればよいと思う -
uv tool run
(uvx
)とuv run
の違い-
uv runは、
python example.py
のようにPythonファイルを実行するときに、通常であればvenvをactivateしていなければいけなかったり実行環境を自前で管理しなければいけなかったが、uv run example.py
のように実行すればuvがプロジェクトの依存関係を自動で解決して実行してくれる - ruffがインストールされてない状態で
uv run ruff
などするとprogram not found
となる - プロジェクトフォルダ(pyproject.tomlがあるフォルダ)で
uv run
すると実行前に依存関係がインストールされる。プロジェクトに存しないスクリプトを実行する場合uv run --no-project
とするとこの事前インストールが実行されない
-
uv runは、
- ❌pipxでもそうだったけどパッケージが古くなった(新しいバージョンが存在する)場合に教えてくれる
--outdated
的なオプションが欲しい
pythonプロジェクト管理
init
-
uv init
とプロジェクト名を指定しない場合、カレントディレクトリ直下にpyproject.tomlを作成
カレントディレクトリ名がそのままプロジェクト名として作成される -
uv init hello-world
とプロジェクト名を指定した場合、指定したプロジェクト名のディレクトリを作成して、そのディレクトリ下にpyprojectが作成される
はじめてのスクリプト実行
- サンプルスクリプト(
hello.py
)が同時に作成されるの -
uv python pin 3.10
などでバージョン固定- initした時
requires-python = ">=3.12"
とかになってて3.10指定すると失敗する - pyproject.tomlを更新してからpinをする
- initした時
-
uv run hello.py
を実行すると- pinしたpythonがインストールされてない場合はインストールされる
- (ない場合は)uv.lockファイルが生成される
- (ない場合は).venvフォルダが作成される。pinしたpythonが変更されてたりするといったん削除されて再作成される
- スクリプトが実行される
依存パッケージ追加・削除・同期
-
uv add boto3
とするとpyprojectのdependenciesにパッケージ追加、.venvフォルダにパッケージがインストールされる-
--no-sync
オプション付けるとパッケージのインストールは行わない -
--dev
つけるとdev-dependenciesにパッケージ追加
-
-
uv add
とuv pip install
の違い- add: pyprojectのdependenciesに追加される
- pip install: 通常のpipと似た動作。pyprojectに追加されず.venvにインストールされる
venvをactivateしなくてもvenvにパッケージをインストールするイメージ
-
uv add httpx --optional network
でhttpxライブラリをextraパッケージとして追加[project.optional-dependencies] network = [ "httpx>=0.27.2", ]
-
uv remove httpx --optional network
とするとhttpxは消えるがnetworkオプションは残り続ける[project.optional-dependencies] network = []
- networkオプションを丸っと消す場合は手動でpyprojectを書き換える必要があるっぽい
- pyprojectを手動で書き換えた場合は
uv sync
でuv.lock, .venvを最新の状態に更新する
uv 0.5.14 (9f1ba2b96 2025-01-02) にて確認
uv venv
で作った仮想環境でpip呼び出すとvenv以外のpip(globalのpip)が呼び出される?
uv venv
# windowsの場合
.\venv\Scripts\activate
python -m pip list # module not found error
pip list # ★.venv以外の場所のpipが呼ばれてる
なのでpip installしても.venvの中にパッケージがインストールされてなかった
uv venv
で仮想環境作ったらuv pip
使ってパッケージ管理する必要ありそう(不通にややこしいのでactivateしたら通常通りに使えるとよいが・・・)
(追記)
uv venv --seed
と--seed
オプションをつけるとpipもインストールした状態でvenv作成される
--seed
Install seed packages (one or more of: pip, setuptools, and wheel) into the virtual environment.
Note that setuptools and wheel are not included in Python 3.12+ environments.
May also be set with the UV_VENV_SEED environment variable.
Python3.11以前ではsetuptoolsなどもインストールされる。
実際--seed
オプションつけて作成してみたがvenv作成までにかかる時間がかなり増加するので、uv venv
使うときはuv pip
を合わせてつかう運用に慣れたほうがいいのかも?
uv venv
-> uv pip install xxx
-> uv run hoge.py
の流れ
非uvプロジェクトでuv使う
プロジェクト管理でuvは使ってない既存プロジェクトでuv使う場合
-
uv python pin 3.x
で.python-version
固定(.python-version
がもとからあるならそれ使う) -
uv venv
で.venvフォルダ作成。固定バージョンのインタプリタがなければさきにインストールされる-
uv venv --python 3.9
などでインタプリタのバージョン指定
-
-
[dev-]requirements.txt
でパッケージ管理してる場合uv pip install -r requirements.txt
- poetryとかpipenvとかの場合
-
uv tool install poetry
/uvx poetry
などで既定のツール使うしかないか
-
- pyprojectがない(pyproject中にprojectの記述がない)場合に
uv run
するとerrorになるっぽいerror: No 'project' table found in: "......./pyproject.toml"
- 仕方ないから
uvx
で実行した
v0.5.0でインストール先のフォルダが変更になった
v0.4.xまでは~/.cargo/bin
にインストールされてたのが~/.local/bin
に変更になったらしい
windowsの場合はC:\Users\{UserName}\.local/bin
windows環境下でv0.4.20からuv self update
して0.5.0にあげたところ、command not foundとなってしまった。
C:\Users\{UserName}\.cargo/bin
ではなくC:\Users\{UserName}\.cargo
の下にuv.exe
とuvx.exe
があるが前からそうだっけ?とにかく.local/bin
にはいなかった
tree
treeコマンドで依存関係ツリーを出力できる
-
uv tree
: pyproject(uv.lock?)に記載の依存関係を出力 -
uv pip tree
: venvにインストールされてるパッケージの依存関係を出力
> uv init
> uv add boto3
> uv pip install requests
> uv tree
sample_prj v0.1.0
└── boto3 v1.37.7
├── botocore v1.37.7
│ ├── jmespath v1.0.1
│ ├── python-dateutil v2.9.0.post0
│ │ └── six v1.17.0
│ └── urllib3 v2.3.0
├── jmespath v1.0.1
└── s3transfer v0.11.4
└── botocore v1.37.7 (*)
(*) Package tree already displayed
> uv pip tree
boto3 v1.37.7
├── botocore v1.37.7
│ ├── jmespath v1.0.1
│ ├── python-dateutil v2.9.0.post0
│ │ └── six v1.17.0
│ └── urllib3 v2.3.0
├── jmespath v1.0.1
└── s3transfer v0.11.4
└── botocore v1.37.7 (*)
requests v2.32.3
├── certifi v2025.1.31
├── charset-normalizer v3.4.1
├── idna v3.10
└── urllib3 v2.3.0
(*) Package tree already displayed
uv pip install
したときにpermission denied
trouble: windows, uv==0.6.12
> uv venv --python 3.11
> uv pip install -r requirements.txt
× Failed to build `hoge`
├─▶ The build backend returned an error
╰─▶ Call to `setuptools.build_meta:__legacy__.build_wheel` failed (exit code: 1)
[stderr]
error: [Errno 13] Permission denied: 'D:\\Users\\user_name\\AppData\\Local\\uv\\cache\\builds-v0\\.tmpQOkP4D\\Lib\\site-packages\\setuptools\\_distutils\\command\\install_scripts.py'
chache内のseuptoolsをどうこうしようとしている?様子
↑を参考にしてuv cache clean
するととりあえず動いた
uv run
するときに--with
オプションをつけることで
uv run --with 'rich>12,<13' example.py
のように依存パッケージを指定してスクリプトを実行できるが、
uv add --script example.py 'requests<3' 'rich'
とすると、example.py
のトップセクションに依存関係を記述したコメントが追加される
# /// script
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
import requests
from rich.pretty import pprint
これでuv run example.py
すれば依存関係を使用して実行してくれるのでわざわざ実行時にパッケージを指定する必要がない
pythonバージョンの指定もできる。このときdependenciesが必要なくとも空のリストを定義しとく必要がある
# /// script
# requires-python = ">=3.12"
# dependencies = []
# ///
# Use some syntax added in Python 3.12
type Point = tuple[float, float]
print(Point)
requirements.txtからimportもできる
uv add -r requirements.txt --script example.py
runに--with-requirements
コマンド付けたらrequirements込みで実行できたのでrequirementsがすでにある場合はこっちでも
uv run --with-requirements requirements.txt example.py
依存パッケージのバージョン更新
uv 0.8.14で確認
多分結論
-
uv add
でパッケージ追加したらpyproject.tomlのdependenciesにパッケージ追加されるが、それ以降はコマンド経由でdependenciesの記述を更新はできない- 参考Issue "We don't support "bumping" the dependency constraints in your pyproject.toml yet. " 古いIssueだがここから変わってなさそう
- 依存関係を更新したい場合は以下の手順
- pyproject.tomlのdpendenciesのバージョンを手動で書き換える
-
uv sync -U
もしくはuv lock -U
- lockファイルだけ更新したいかvenv下も更新したいかで使い分ける
検証
-
uv add requests==2.20.0
- pyprojecto.tomlのdependenciesに
"requests==2.20.0"
が追加される
- pyprojecto.tomlのdependenciesに
-
uv add requests>=2.19.0
- pyprojecto.tomlのdependenciesに変更はない
-
uv pip list
してみてもrequests==2.20.0のまま
-
uv add requests>=2.21.0
- pyprojecto.tomlのdependenciesに変更はない
-
uv pip list
してみてもrequests==2.20.0のまま
- uv add -U requests>=2.21.0
- pyprojecto.tomlのdependenciesに変更はない
- "requests>=2.20.0"にdependenciesに書き換えたうえで
uv add -U requests>=2.21.0
- pyprojecto.tomlのdependenciesに変更はない
- lockファイルの更新とバージョンに合わせたパッケージがインストールされる
-
requests==2.20.0
に手動でpyproject記述を戻してからuv sync
- lockファイルの記述が2.20.0に代わってvenv内のバージョンも2.20.0になる
- その状態で
requests>=2.20.0
に手動で記述を書き換えてからuv sync
- lockファイルもvenvも更新されない
- その状態で
uv sync -U
- lockファイルもvenvも更新されて最新バージョンになっている