uv 0.13を0.12と比べて検証|Python 3.15が既定になり、制約の指定で3つの書き方がエラーに
uv 0.13で、Python 3.15が既定になり、制約ファイルの扱いが厳しくなった
PythonのパッケージとPythonそのものを管理するツールuvの0.13.0を、開発元のAstralが10月10日(日本時間)に公開しました。11月3日には0.13.7が出ています。0.13は、版を指定せずにPythonを取得するときの既定を3.14から3.15に変え、いくつかの破壊的変更をまとめた版です。リリースノートは「ほとんどの利用者は変更なしで上げられる見込み」としつつ、これまで黙って通っていた書き方の一部がエラーになると説明しています。
この記事は、手元の開発やCIでuvを使っていて、0.12から上げる前に影響を確かめたい人に向けたものです。0.12.24と0.13.7をそれぞれ別の仮想環境に入れ、uvが取得するPythonの置き場所も版ごとに分けて、同じ操作の結果を比べました(キャッシュは、取り直しを確かめる比較だけ共通にしました)。手元で確かめた6つの変化と、エラーになった書き方の直し方をまとめます。
記事の要点
0.12.24で通っていた制約の指定の3つの書き方が、0.13.7ではエラーで止まった
2026年11月9日、MacでuvのPyPI版0.12.24と0.13.7を比べた結果です。
既定のPython
版を指定せずに取得すると3.15が入る
PATHにあるPythonや入っているPythonは、そのまま使います。3.14に留めるなら uv python pin 3.14。
エラーになる書き方
読み込む制約ファイルの --require-hashes と -e、-c の空白区切り
どれも0.12.24では警告なしで通り、0.13.7では止まりました。
仮想環境
_virtualenv.pth が入らなくなった
Python 3.10以降で新しく作る仮想環境が対象で、作ってある環境はそのままです。
キャッシュ
上げた直後は、パッケージを取り直す
0.12.24で作ったキャッシュがあっても、0.13.7の初回は6つを取得し直しました。
0.12.24と0.13.7で比べた6つの変化
リリースノートにある破壊的変更のうち、Macの手元で再現できる5つと、キャッシュの扱いの変化の、合わせて6つを確かめました。下の表は、同じ操作をしたときのそれぞれの版の結果です。
同じ操作をしたときの結果
| 操作 | 0.12.24 | 0.13.7 |
|---|---|---|
版を指定せずに uv python install | 3.14.8を入れた | 3.15.2を入れた |
要件ファイルから読み込む制約ファイルに --require-hashes | ハッシュなしで入った | エラー |
要件ファイルから読み込む制約ファイルに -e ./localpkg | 黙って無視した | エラー |
コマンドで -c "c1.txt c2.txt" | 2つのファイルとして読んだ | エラー(1つのパスとして探す) |
新しい仮想環境(uv venv)の中身 | _virtualenv.pth と _virtualenv.py がある | どちらもない |
0.12.24のキャッシュで uv pip install | 2回目はキャッシュから入れた | 初回は6つを取得し直した |
2026年11月9日、macOS 27.0.1(Apple Silicon)で確認。uvはPyPIのパッケージを版ごとの仮想環境に入れて試しました。uv python install は既定の設定、ほかはuvが管理するPythonだけを使う設定(UV_PYTHON_PREFERENCE=only-managed)で試しました。
版を指定せずにPythonを取得すると、3.15が入る
変わったのは、uvが版の指定なしでPythonを取得するときの既定です。版を指定せずに uv python install を実行すると、0.12.24は3.14.8を、0.13.7は3.15.2を入れました。
# uv 0.12.24(既定の設定)
$ uv python install
Downloading cpython-3.14.8-macos-aarch64-none (download) (25.4MiB)
Downloaded cpython-3.14.8-macos-aarch64-none (download)
Installed Python 3.14.8 in 4.71s
+ cpython-3.14.8-macos-aarch64-none
# uv 0.13.7(既定の設定)
$ uv python install
Downloading cpython-3.15.2-macos-aarch64-none (download) (26.5MiB)
Downloaded cpython-3.15.2-macos-aarch64-none (download)
Installed Python 3.15.2 in 4.30s
+ cpython-3.15.2-macos-aarch64-none
uv venv などは、PATHにあるPythonやuvが入れたPythonが見つかれば、0.13でもそれを使います。手元のMacでは、既定の設定の uv venv は、0.12.24も0.13.7も、このMacのPATHに以前から入っていた3.15.2を使い、何も取得しませんでした。uvが管理するPythonだけを使う設定で、3.13だけを入れてある状態でも、0.13.7は3.13を使いました。使えるPythonが1つも見つからないとき、たとえばPythonの入っていないコンテナでCIを動かす場合や、uvが管理するPythonだけを使う設定でまだ1つも入れていない場合は、0.13で3.15を取得します。
# uv 0.12.24(uvが管理するPythonだけを使う設定で、まだ1つも入っていない状態)
$ uv venv
Downloading cpython-3.14.8-macos-aarch64-none (download) (25.4MiB)
Downloaded cpython-3.14.8-macos-aarch64-none (download)
Using CPython 3.14.8
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
$ ls .venv/lib/python3.*/site-packages
_virtualenv.pth
_virtualenv.py
# uv 0.13.7(同じ設定・同じ状態)
$ uv venv
Downloading cpython-3.15.2-macos-aarch64-none (download) (26.5MiB)
Downloaded cpython-3.15.2-macos-aarch64-none (download)
Using CPython 3.15.2
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
$ ls .venv/lib/python3.*/site-packages
(何も表示されない)
3.14に留めたいときは、版を指定するか、uv python pin で .python-version に書いておきます。
$ uv venv --python 3.14
Using CPython 3.14.10
$ uv python pin 3.14 && uv venv
Pinned `.python-version` to `3.14`
Using CPython 3.14.10
Python 3.15で変わる点(open() の既定の文字コードなど)は、Python 3.15を3.14と比べて検証した記事にまとめています。
制約の指定で、0.13ではエラーになる3つの書き方
要件ファイル(requirements)は入れるパッケージを並べるファイル、制約ファイル(constraints)は入れるパッケージの版の範囲だけを決めるファイルです。制約ファイルは、要件ファイルの中から -c の行で読み込んだり、コマンドの -c で渡したりします。0.12.24では警告なしで通っていた次の3つの書き方が、0.13.7ではエラーで止まりました。1と2は、要件ファイルの中から読み込む制約ファイルでの変化です(同じ制約ファイルをコマンドの -c で直接渡した場合は、0.12でも同じようにエラーになります)。試したファイルの中身です。
# req-hashes.txt(制約ファイルに --require-hashes がある)
-c constraints-hashes.txt
idna
six
# constraints-hashes.txt
--require-hashes
idna==3.10 --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3
# req-editable.txt(制約ファイルに -e がある)
-c constraints-editable.txt
idna
# constraints-editable.txt
-e ./localpkg
idna==3.10
$ uv --version
uv 0.13.7 (316c827e0 2026-11-03 aarch64-apple-darwin)
# 1. 制約ファイルに --require-hashes がある
$ uv pip install -r req-hashes.txt
error: In `--require-hashes` mode, all requirements must have their versions pinned with `==`, but found: idna
# 2. 制約ファイルに -e がある
$ uv pip install -r req-editable.txt
error: Editable requirements are not allowed as constraints in `constraints-editable.txt`
# 3. -c に2つのファイルを空白区切りで渡す
$ uv pip install -r req-plain.txt -c "c1.txt c2.txt"
error: File not found: c1.txt c2.txt
0.12.24では、1は --require-hashes を無視してハッシュのない six まで入れ、2は -e ./localpkg を無視して idna だけを入れ、3は2つのファイルとして読んで、どれも終了コード0で終わりました。それぞれの直し方を、0.13.7で通るところまで確かめました。
1. --require-hashes:すべての依存を固定してハッシュを付ける
読み込む制約ファイルに --require-hashes があると、0.13ではインストールするすべての要件に、== での版の固定とハッシュが要ります。uv pip compile の --generate-hashes で、制約(ここでは idna==3.10 だけを書いた c1.txt)に合わせて固定したファイルを作ると通りました。ハッシュを確かめるつもりがなかったなら、制約ファイルから --require-hashes を消します。
# req.in には idna と six を書いておく
$ cat c1.txt
idna==3.10
$ uv pip compile req.in -c c1.txt --generate-hashes -o req-locked.txt
$ grep -E '^[a-z]' req-locked.txt
idna==3.10 \
six==1.17.0 \
$ uv pip install -r req-locked.txt -c constraints-hashes.txt
Resolved 2 packages in 0.41ms
Prepared 1 package in 46ms
Installed 2 packages in 1ms
+ idna==3.10
+ six==1.17.0
2. 制約ファイルの -e:要件ファイルへ移す
手元で開発中のパッケージを -e で入れる行は、制約ファイルから要件ファイル(-r で渡すファイル)へ移すか、コマンドの --editable で渡します。pipも同じ書き方を求めています。
# req-editable-fixed.txt(-e を要件ファイルへ移した。constraints-plain.txt は idna==3.10 の1行)
-c constraints-plain.txt
-e ./localpkg
idna
$ uv pip install -r req-editable-fixed.txt
Resolved 2 packages in 1ms
Building localpkg @ file:///…/localpkg
Built localpkg @ file:///…/localpkg
Prepared 1 package in 10ms
Installed 2 packages in 1ms
+ idna==3.10
+ localpkg==0.1.0 (from file:///…/localpkg)
3. -c の空白区切り:オプションを繰り返す
0.13では、-c、--override、--exclude、--build-constraint に渡した値を1つのパスとして扱います。空白を含むパスを渡せるようになった代わりに、複数のファイルはオプションを繰り返して渡します。環境変数の UV_CONSTRAINT は、空白区切りのままで通りました(リリースノートでは UV_OVERRIDE などほかの環境変数も同じ扱い)。
# -c を繰り返す
$ uv pip install -r req-plain.txt -c c1.txt -c c2.txt
Resolved 1 package in 78ms
Prepared 1 package in 21ms
Installed 1 package in 1ms
+ idna==3.10
# 環境変数 UV_CONSTRAINT は、空白区切りのまま使える
$ UV_CONSTRAINT="c1.txt c2.txt" uv pip install -r req-plain.txt
Resolved 1 package in 0.41ms
Installed 1 package in 0.86ms
+ idna==3.10
仮想環境のファイルと、キャッシュの取り直し
0.12.24は新しい仮想環境に _virtualenv.pth と _virtualenv.py を入れていました。distutilsの設定がインストール先を変えないようにするためのファイルで、0.13はPython 3.10以降の環境ではこの2つを入れません(Pythonの節の出力で、ls の結果が空になっている部分)。作ってある仮想環境は自動では変わらず、作り直すとファイルがなくなります。
0.13ではキャッシュの形式も変わっています。同じキャッシュのディレクトリを使って試すと、0.12.24で取得済みの6つのパッケージを、0.13.7は初回にもう一度取得しました。リリースノートは、上げたあとに依存をダウンロードし直したりビルドし直したりすることがあるとしています。CIでキャッシュを保存している場合、上げた直後の1回は時間が増えます。
# 同じキャッシュのディレクトリを使い、それぞれの版で2回ずつ入れる
$ uv pip install -r req.txt # 0.12.24、1回目
Resolved 6 packages in 156ms
Prepared 6 packages in 143ms
Installed 6 packages in 6ms
$ uv pip install -r req.txt # 0.12.24、2回目
Resolved 6 packages in 1ms
Installed 6 packages in 2ms
$ uv pip install -r req.txt # 0.13.7、1回目
Resolved 6 packages in 151ms
Prepared 6 packages in 133ms
Installed 6 packages in 4ms
$ uv pip install -r req.txt # 0.13.7、2回目
Resolved 6 packages in 0.80ms
Installed 6 packages in 2ms
リリースノートにあるほかの変更
次の変更は、Macの手元の比較には入れていません。該当する使い方をしているかを、0.13.0のリリースノートで確かめます。
- WindowsのARM64版のuvが、エミュレーションで動くx86_64版のPythonより、ARM64版のPythonを優先するようになりました。従来どおりにするには
UV_PYTHON_ARCH=x86_64を指定します。 - tarアーカイブを読む部品が、より厳しく検査する
tar-codecに変わりました。0.13.0で読めなくなったハードリンクを含むソース配布物などは、0.13.1で再び読めるようになっています。それでも読めないアーカイブがあるときは、UV_LEGACY_TAR_BACKEND=1で従来の部品に戻せます。uv_buildで作るソース配布物のバイト列とハッシュは変わることがあります。 uv build --clearは、出力先がビルドの元のディレクトリを含むと、消す前に拒否するようになりました。[build-system]でuv_buildの版に<0.13のような上限を付けている場合は、uv_build>=0.13.0,<0.14のように0.13を含む範囲へ変えます。
0.13へ上げる前に確かめる手順
1
プロジェクトとCIで使うPythonの版を、.python-version などで決めてあるかを見る
2
要件ファイルの -c 行で読み込む制約ファイルに --require-hashes や -e がないか、コマンドの -c に空白区切りで渡していないかを探す
3
uvを上げ、いつものインストールを1回流してエラーがないかを確かめる
uvの更新は、入れた方法ごとに行います。uvのインストール手順のページは、公式のインストーラーで入れた場合は uv self update、それ以外はその方法の更新手順を使うとしています。Homebrewのuvは、11月9日の時点で0.13.7になっています。
# 入れた方法に合わせて上げる
uv self update # 公式のインストーラーで入れた場合
brew upgrade uv # Homebrew
pipx upgrade uv # pipx
pip install --upgrade uv # pip
uv --version # 0.13 以降になったかを確かめる
読み込んでいる制約ファイルは、リポジトリの直下で grep -rnE --include='*.txt' --include='*.in' '^(-c|--constraint)[ =]' . と検索すると、要件ファイルの -c 行や --constraint 行から分かります。見つかった制約ファイルを開いて、--require-hashes と行頭の -e がないかを確かめます。CIの設定では、-c や --constraint に空白を含む値を渡していないかを見ます。
参考資料
- uv 0.13.0のリリースノート(2026年10月9日、米国時間): Python 3.15の既定化と破壊的変更、キャッシュ形式の変更
- uv 0.13.7のリリースノート(2026年11月3日)
- プルリクエスト: #22275(制約ファイルの
--require-hashes)、#22282(制約ファイルの-e)、#22290(パスの扱い)、#22096(distutilsのパッチ) - uvの文書「Installation」: 更新の方法
検証環境
- macOS 27.0.1(Apple Silicon)
- uv 0.12.24と0.13.7(PyPIのパッケージ)、uvが取得したCPython 3.13.16、3.13.18、3.14.8、3.14.10、3.15.2
- 検証日: 2026年11月9日
この記事は、AIが調査と下書きを担当し、上記の環境で実際に動かして結果を確かめ、下書きとは別の担当が公開前に本文と出典を確認しています。制作と訂正の方針は編集・訂正方針で公開しています。











