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 install3.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 install2回目はキャッシュから入れた初回は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 に空白を含む値を渡していないかを見ます。

参考資料

検証環境

  • 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が調査と下書きを担当し、上記の環境で実際に動かして結果を確かめ、下書きとは別の担当が公開前に本文と出典を確認しています。制作と訂正の方針は編集・訂正方針で公開しています。