Resolution#
解決とは、要件のリストを取得し、要件を満たすパッケージ・バージョンのリストに変換するプロセスです。解決には、パッケージの互換性のあるバージョンを再帰的に検索し、要求された要件が満たされ、要求されたパッケージの要件に互換性があることを確認する必要があります。
Dependencies#
ほとんどのプロジェクトとパッケージには依存関係があります。依存関係とは、現在のパッケージが動作するために必要な他のパッケージです。パッケージは、その依存関係を_requirements_として定義します。これは、パッケージ名と受け入れ可能なバージョンの大まかな組み合わせです。現在のプロジェクトによって定義される依存関係は_direct dependencies_と呼ばれます。現在のプロジェクトの各依存関係によって追加される要件は_indirect_または_transitive dependencies_と呼ばれます。
Note
依存関係の詳細については、Python Packagingドキュメントのdependency specifiers pageを参照してください。
Basic examples#
解決プロセスをわかりやすく説明するために、次の依存関係を考慮してください。
- プロジェクトは
fooとbarに依存しています。 fooにはバージョン1.0.0があります:foo 1.0.0はlib>=1.0.0に依存します。
barにはバージョン1.0.0があります:bar 1.0.0はlib>=2.0.0に依存します。
libには1.0. 0と2.0. 0の2つのバージョンがあります。どちらのバージョンにも依存関係はありません。
この例では、リゾルバはプロジェクトの要件を満たすパッケージバージョンのセットを見つけなければなりません。fooとbarの両方に1つのバージョンしかないので、それらが使用されます。解決には推移的な依存関係も含まれている必要があるので、libのバージョンを選択する必要があります。foo 1.0.0はlibの利用可能なすべてのバージョンを許可しますが、bar 1.0.0はlib>=2.0.0を必要とするので、lib 2.0.0を使用する必要があります。
解決策によっては、複数の解決策が存在する場合があります。次の依存関係を考慮してください。
- プロジェクトは
fooとbarに依存しています。 fooには1.0.0と2.0.0の2つのバージョンがあります:foo 1.0.0には依存関係がありません。foo 2.0.0はlib==2.0.0に依存します。
barには1.0.0と2.0.0の2つのバージョンがあります:bar 1.0.0には依存関係がありません。bar 2.0.0はlib==1.0.0に依存します
libには1.0. 0と2.0. 0の2つのバージョンがあります。どちらのバージョンにも依存関係はありません。
この例では、fooとbarの両方のいくつかのバージョンを選択する必要がありますが、どちらのバージョンを選択するかを決定するには、fooとbarの各バージョンの依存関係を考慮する必要があります。foo 2.0.0とbar 2.0.0は、必要なlibのバージョンで競合するため、一緒にインストールすることはできません。そのため、リゾルバはfoo 1.0.0かbar 1.0.0のいずれかを選択する必要があります。どちらも有効なソリューションであり、異なる解決アルゴリズムによってどちらかの結果が得られる場合があります。
Platform markers#
マーカーを使用すると、依存関係をいつ使用すべきかを示す式を要件に付加できます。たとえば、bar;python_version<"3.9"は、Python 3.8以前ではbarのみを要求するために使用できます。
マーカーは、現在の環境またはプラットフォームに依存するパッケージの依存関係を調整するために使用されます。たとえば、マーカーを使用して、オペレーティングシステム、CPUアーキテクチャ、Pythonバージョン、Python実装などに基づいて依存関係を変更できます。
Note
マーカーの詳細については、Python Packagingドキュメントのenvironment markersセクションを参照してください。
マーカーは、その値によって必要な依存関係が変更されるため、解決に重要です。通常、Pythonパッケージリゾルバは、_current_platformのマーカーを使用して、使用する依存関係を決定します。これは、パッケージが現在のプラットフォームに_インストール_されていることが多いためです。ただし、_locking_dependenciesの場合、これには問題があります。ロックファイルは、ロックファイルが作成されたのと同じプラットフォームを使用している開発者に対してのみ機能します。この問題を解決するために、プラットフォームに依存しない、または「ユニバーサル」リゾルバが存在します。
uvは、platform-specificとuniversalの両方の解像度をサポートします。
Universal resolution#
uvのロックファイル(uv.lock)は、ユニバーサル解像度で作成され、プラットフォーム間で移植可能です。これにより、オペレーティングシステム、アーキテクチャ、Pythonのバージョンに関係なく、プロジェクトで作業するすべての人の依存関係がロックされます。uvロックファイルは、uv lock、uv sync、uv addなどのprojectコマンドによって作成および変更されます。
universal resolutionは、uvのpipインタフェース、つまりuv pip compileでも--universalフラグを付けて使用できます。結果の要件ファイルには、各依存関係がどのプラットフォームに関連しているかを示すマーカーが含まれます。
ユニバーサル解像度では、異なるプラットフォームに異なるバージョンが必要な場合、パッケージが異なるバージョンまたはURLで複数回リストされることがあります。使用されるバージョンはマーカーによって決定されます。ユニバーサル解像度は、すべてのマーカーの要件を考慮する必要があるため、プラットフォーム固有の解像度よりも制約が多いことがよくあります。
ユニバーサル解決では、Pythonの最小バージョンを指定する必要があります。プロジェクトコマンドは、pyproject.toml内のproject.requires-pythonから必要な最小バージョンを読み込みます。pipインタフェースを使用する場合は、--python-versionオプションで値を指定します。そうしないと、現在のPythonバージョンが下限として扱われます。たとえば、--universal--python-version 3.9は、Python 3.9以降のユニバーサル解決を書き込みます。
選択するすべてのパッケージバージョンがPythonのバージョン範囲と互換性がある必要があるため、Pythonの最小バージョンを設定することは重要です。たとえば、--python-version 3.8でのnumpy<2という普遍的な解決はnumpy==1.24.4に解決されますが、--python-version 3.9はnumpy==1.26.4に解決されます。これは、1.26.4年以降のnumpyリリースではPython 3.9+が必要になるためです。Pythonの要件の下限のみを考慮し、上限は常に無視されることに注意してください。
Platform-specific resolution#
デフォルトでは、uvのpipインタフェース、つまりuv pip compileは、pip-toolsのようにプラットフォーム固有の解像度を生成します。uvのプロジェクトインタフェースでプラットフォーム固有の解像度を使用する方法はありません。
また、uvは--python-platformおよび--python-versionオプションを使用して、特定の代替プラットフォームおよびPythonバージョンの解決もサポートしています。たとえば、macOSでPython 3.12を使用している場合、代わりにuv pip compile--python-platform linux--python-version 3.10 requirements.inを使用して、LinuxでPython 3.10の解決を生成できます。ユニバーサル解決とは異なり、プラットフォーム固有の解決では、指定された--python-versionは使用するPythonの正確なバージョンであり、下限ではありません。
Note
Pythonの環境マーカーは、単純な--python-platform引数で表現できるよりも、現在のマシンに関するはるかに多くの情報を公開します。例えば、macOSのplatform_versionマーカーには、カーネルが構築された時刻が含まれていますが、これは(理論的には)パッケージ要件でエンコードすることができます。uvのリゾルバは、ターゲット--python-platformで実行されている任意のマシンと互換性のある解決を生成するために最善の努力を払います。これは、ほとんどのユースケースで十分であるはずですが、複雑なパッケージとプラットフォームの組み合わせでは忠実度を失う可能性があります。
Dependency preferences#
uvロックファイル(uv.lock)や要件出力ファイル(requirements.txt)などの解決出力ファイルが存在する場合、uvはそこにリストされている依存関係のバージョンを優先します。同様に、パッケージを仮想環境にインストールする場合、uvはすでにインストールされているバージョンを優先します(存在する場合)。これは、互換性のないバージョンが要求されたり、--upgradeで明示的にアップグレードが要求されたりしない限り、ロックされたバージョンやインストールされたバージョンは変更されないことを意味します。
Resolution strategy#
デフォルトでは、uvは各パッケージの最新バージョンを使用しようとします。たとえば、uv pip install flask>=2.0. 0は、Flaskの最新バージョン(3.0. 0など)をインストールします。flask>=2.0. 0がプロジェクトの依存関係である場合は、flask3.0. 0のみが使用されます。たとえば、テストを実行しても、プロジェクトが指定されたflask2.0. 0の下限と実際に互換性があるかどうかはチェックされないため、これは重要です。
--resolution lowestを使用すると、uvはすべての依存関係に対して、直接的にも間接的(推移的)にも、可能な限り低いバージョンをインストールします。あるいは、--resolution lowest-directは、すべての直接的依存関係に対して互換性のある最も低いバージョンを使用し、他のすべての依存関係に対して互換性のある最新のバージョンを使用します。uvは常にビルドの依存関係に最新のバージョンを使用します。
たとえば、次のrequirements.inファイルがあるとします。:
uv pip compile requirements.inを実行すると、次のrequirements.txtファイルが生成されます。
# This file was autogenerated by uv via the following command:
# uv pip compile requirements.in
blinker==1.7.0
# via flask
click==8.1.7
# via flask
flask==3.0.0
itsdangerous==2.1.2
# via flask
jinja2==3.1.2
# via flask
markupsafe==2.1.3
# via
# jinja2
# werkzeug
werkzeug==3.0.1
# via flask
しかし、uv pip compile--resolution lowest requirements.inは代わりに以下を生成します。
# This file was autogenerated by uv via the following command:
# uv pip compile requirements.in --resolution lowest
click==7.1.2
# via flask
flask==2.0.0
itsdangerous==2.0.0
# via flask
jinja2==3.0.0
# via flask
markupsafe==2.0.0
# via jinja2
werkzeug==2.0.0
# via flask
ライブラリを公開する場合は、宣言された下限との互換性を保証するために、継続的インテグレーションで--resolution lowestまたは--resolution lowest-directを使用してテストを個別に実行することをお勧めします。
Pre-release handling#
デフォルトでは、uvは次の2つの場合に、依存関係の解決中にプレリリースバージョンを受け入れます。
- パッケージが直接の依存関係であり、そのバージョン指定子にプレリリース指定子が含まれている場合(例:
flask>=2.0.0rc1)。 - パッケージの_すべての_公開されたバージョンがプレリリースである場合。
推移的なプレリリースが原因で依存関係の解決に失敗した場合、uvはすべての依存関係に対してプレリリースを許可するために--prerelease allowの使用を促します。
あるいは、その特定の依存関係のプレリリースサポートにオプトインするために、constraintまたは直接依存関係(すなわち、requirements.inまたはpyproject.toml)として、プレリリースバージョン指定子(例えばflask>=2.0.0rc1)とともに推移的依存関係を追加することもできます。
プレリリースはモデル化がnotoriously difficultであり、他のパッケージングツールのバグの原因となることがよくあります。uvのプレリリース処理は_意図的に_制限されており、正確さを保証するためにプレリリースに対してユーザのオプトインを必要とします。
For more details, see Pre-release compatibility.
詳細については、Pre-release compatibilityを参照してください。
Dependency constraints#
uvは、pipのような制約ファイル(--constraint constraints.txt)をサポートしています。これは、指定されたパッケージに対して受け入れ可能なバージョンのセットを絞り込みます。制約ファイルは通常の要件ファイルと似ていますが、パッケージを要件に追加するものではありません。パッケージが直接または推移的な依存関係で要求された場合にのみ有効になります。制約は、パッケージに直接要件を追加せずに、推移的な依存関係に対して使用可能なバージョンの範囲を減らす場合に便利です。
Dependency overrides#
オーバーライドを使用すると、宣言されたパッケージの依存関係をオーバーライドすることによって、失敗した解決や望ましくない解決をバイパスできます。オーバーライドは、依存関係が宣言されているよりも新しいバージョンのパッケージと互換性があることがわかっていても、その互換性を宣言するためにまだ更新されていない場合に便利な最後の手段です。
例えば、推移的な依存関係が要件pydantic>=1.0,<2.0を宣言しているが、pydantic>=2.0で動作する場合、ユーザは宣言された依存関係をpydantic>=1.0,<3で上書きして、リゾルバがpydanticの新しいバージョンをインストールできるようにすることができます。
制約と依存関係は純粋に追加的なものであるため、パッケージの受け入れ可能なバージョンのセットを拡張することはできないが、オーバーライドはパッケージの受け入れ可能なバージョンのセットを拡張し、誤ったバージョンの上限に対するエスケープハッチを提供することができる。制約と同様に、オーバーライドはパッケージに依存関係を追加せず、パッケージが直接または推移的な依存関係で要求された場合にのみ有効になる。
pyproject.tomlでは、tool.uv.override-dependenciesを使用してオーバーライドのリストを定義します。pip互換インタフェースでは、--overrideオプションを使用して、制約ファイルと同じ形式のファイルを渡すことができます。
If multiple overrides are provided for the same package, they must be differentiated with markers. If a package has a dependency with a marker, it is replaced unconditionally when using overrides — it does not matter if the marker evaluates to true or false.
同じパッケージに対して複数のオーバーライドが指定されている場合は、markersで区別する必要があります。パッケージにマーカーとの依存関係がある場合、オーバーライドを使用すると無条件に置き換えられます。マーカーがtrueと評価されるかfalseと評価されるかは関係ありません。
Reproducible resolutions#
uvは--exclude-newerオプションをサポートしており、特定の日付よりも前に公開されたディストリビューションに解決を制限し、新しいパッケージのリリースに関係なくインストールの再現を可能にします。日付は、RFC 3339タイムスタンプ(例:2006-12-02T02:07:43Z)または同じ形式のUTC日付(例:2006-12-02)として指定できます。
パッケージインデックスは、PEP 700で指定されているupload-timeフィールドをサポートしている必要があることに注意してください。このフィールドが指定されたディストリビューションに存在しない場合、そのディストリビューションは利用できないものとして扱われます。PyPIはすべてのパッケージにupload-timeを提供しています。
再現性を保証するために、満足できない解決のためのメッセージは、--exclude-newerフラグのために配布が除外されたことを言及しません。新しい配布は、存在しないものとして扱われます。
Learn more#
For more details about the internals of the resolver, see the resolver reference documentation.
リゾルバの内部の詳細については、resolver referenceドキュメントを参照してください。