uv syncで新しい依存が入らない?lockedとfrozenの違いとlock更新漏れ

--lockedはuv.lockの更新が必要か検査し、--frozenはその検査を省いて既存lockを使う。両方ともlockを自動更新しない比較図。

対象はpyproject.tomlとuv.lockを使うuvプロジェクトです。

uv sync --frozenが成功しても、現在のpyproject.tomlとuv.lockが整合している証明にはなりません。--frozenは既存のlockをそのまま採用し、現在の設定と合っているかの検査を省くためです。依存追加のlock更新漏れを止めたいならuv sync --locked、環境を同期せずlockだけ確認したいならuv lock --checkを使います。意図した変更ならuv lockで取り込み、--lockedで再確認します。

目次

指定なし・--locked・--frozenの違い

uv公式のLocking and syncingでは、通常のuv syncやuv runは必要に応じてlockと環境を更新すると説明されています。--lockedと--frozenはいずれも自動lock更新を避けますが、古いlockを検査するかどうかが異なります。

実行方法lockの現在性確認lockの自動更新古いlockがあるとき
指定なし行う必要なら行うlockを更新して同期する
--locked行う行わない更新せずエラーにする
--frozen行わない行わない既存lockの内容で同期する
pyproject.tomlに依存を追加した後、lockの更新漏れを検出し、意図した変更ならuv lockとlocked同期を行って両ファイルの差分を確認する手順図。
意図した依存変更を反映する · 図を拡大

--frozenでも環境同期そのものは行います。uv runで環境同期を省く--no-syncとは別の指定です。また、--frozenでuv.lockが存在しなければエラーになります。詳しいオプション定義はuv CLI Referenceで確認できます。

古いuv.lockを再現する

以下は2026年10月6日に、Windows、uv 0.12.23(46b84fd0b、2026-10-03)、Python 3.13.7、隔離した検証用フォルダーと新しい仮想環境で確認した手順です。実測では--pythonでPython 3.13.7の実行ファイルを指定しました。掲載コマンドはPATH上のuvを使う短縮形です。Python選択をそろえるには、uvのオプションとして--python 3.13を指定します。uv runでは実行対象のpythonより前に置きます。パッケージ取得にはインデックスへのネット接続などが必要です。

1. 空依存のlockと環境を作る

空のフォルダーへ次のpyproject.tomlを保存します。

[project]
name = "uv-lock-demo"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = []
uv lock
uv sync --locked

実測では両方とも終了コード0でした。この時点のlockにはidnaを含めません。

2. pyproject.tomlだけ変更する

[project]内の既存のdependencies行を次の1行へ置き換えます。まだuv lockは実行しません。

dependencies = ["idna==3.10"]

--lockedとuv lock --checkで更新漏れを検出する

lockだけを検査する場合は次を実行します。

uv lock --check

同期も行う工程では、次を独立して実行します。

uv sync --locked

実測ではどちらも終了コード1となり、uv.lockの更新が必要であることを示すエラーになりました。SHA256も不変で、検査のためにlockを書き換えてはいません。エラー文言そのものはuvの版によって変わる可能性があります。失敗時に後続処理を止めるCIやシェルでは、確認目的に応じて別々に試してください。

--frozenは成功しても追加依存を取り込まない

uv sync --frozen
uv run --frozen python -c "import importlib.util; print(importlib.util.find_spec('idna') is not None)"

新しい専用環境での実測では、同期は終了コード0、確認出力はFalse、lockのSHA256は不変でした。つまり--frozenは古いlockに従って同期し、pyproject.tomlへ追加したidnaをlockにも環境にも取り込みません。確認用のuv runから--frozenを外すと、自動でlockが更新されて比較条件を壊し得るため、再現中は必ず付けます。すでにidnaが存在する別環境でも同じくFalseになるとは限りません。

意図した依存追加をlockへ反映する

uv lock
uv sync --locked
uv run --locked python -c "import idna; print(idna.__version__)"

実測ではすべて終了コード0となり、uv.lockへidna 3.10が追加され、最後の出力は3.10でした。lockのSHA256も変更されています。pyproject.tomlとuv.lockの差分をレビューし、両方をコミットします。依存追加自体が誤りなら設定側を戻してください。エラーを消すためだけに--lockedを--frozenへ替えたり、lockを削除したりする対処は更新漏れを隠します。

CIとDockerでの使い分け

CIで現在性だけを検査するならuv lock --check、現在性を検査しながら環境も同期するならuv sync --lockedが適します。Dockerでは例外的に、workspaceメンバーの全pyproject.tomlをまだコピーしていない中間レイヤーで--frozenを使い、全ファイルのコピー後に--lockedで検査する構成がuv公式Dockerガイドに示されています。したがって、--frozen自体が常に誤りなのではなく、整合性検査をどの段階で行うかが重要です。

よくある質問

パッケージの新版が公開されると、lockは古い扱いになりますか?

uvは単純なファイル文字列差分ではなく、lockがプロジェクトメタデータに対して現在も有効かを確認します。依存の追加や、既存のlocked版を許容しなくなる制約変更では更新が必要です。一方、locked版を引き続き許容する制約変更や、新しい版が公開されたことだけで必ず古いlockになるわけではありません。

--lockedが成功すれば、依存不足やアプリの不具合も防げますか?

--lockedやuv lock --checkの成功は、アプリケーションの正常動作まで保証しません。依存グループやextrasの選択、別プロジェクトの実行、別Python環境を見ていることによる未導入は、lock更新漏れとは分けて確認します。

依存は入るのに自作コマンドだけ見つからない場合

lock更新漏れとは別に、プロジェクト本体のインストール設定を確認します。uvのproject.scriptsとパッケージ設定を確認する手順を参照してください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次