依存関係解決¶
pip は、パッケージの依存関係を決定してインストールできます。依存関係のどのバージョンをインストールするかを決定するプロセスは、依存関係解決と呼ばれます。この動作は、--no-deps を pip install に渡すことで無効にできます。
動作方法¶
ユーザーが pip install を実行する場合(例: pip install tea)、pip はパッケージの依存関係(例: spoon、hot-water、tea-leaves など)と、それらの依存関係の各バージョンのインストール方法を判断する必要があります。
pip install の実行開始時、pip は要求されたパッケージのすべての依存関係情報を持ちません。要求されたパッケージの依存関係、それらの依存関係の依存関係などを判断する必要があります。依存関係解決プロセスの過程で、pip はパッケージの依存関係を取得するために使用されるパッケージの配布ファイルをダウンロードする必要があります。
バックトラッキング¶
バージョン 20.3 で変更されました:pip の依存関係解決機能は、バックトラッキングに対応しました。
依存関係解決中に、pip はインストールする必要のあるパッケージバージョンの仮定を行い、後でそれらの仮定が間違っていなかったことを確認する必要があります。pip が以前に行った仮定が間違っていたことを検出すると、バックトラックする必要があります。つまり、既に実行された作業の一部を破棄し、別のパスを選択して戻ります。
これは、pip が同じパッケージの複数のバージョンをダウンロードしているように見える可能性があります。これは、pip が各ダウンロードをユーザーに明示的に提示するためです。このステップで行われた選択のバックトラッキングは、予期しない動作やバグではありません。Python パッケージの依存関係解決の動作の一部です。
例
ユーザーが pip install tea を要求します。パッケージ tea は、hot-water、spoon、cup などへの依存関係を宣言します。
pip は、まず最新のバージョンの tea を選択し、そのバージョンの tea の依存関係リストを取得します。次に、spoon、cup の最新のバージョンを選択して、それらのパッケージについてもこのプロセスを繰り返します。ここで、pip は選択した cup のバージョンが選択した spoon のバージョンと互換性がないことに気づきます。そのため、pip は「戻る」(バックトラック)して、別のバージョンの cup を使用しようとします。成功すると、次のパッケージ(sugar など)に進みます。そうでない場合は、他のすべてのパッケージと互換性のあるバージョンの cup が見つかるまで、cup でバックトラックを続けます。
これは次のように見えます。
$ pip install tea
Collecting tea
Downloading tea-1.9.8-py2.py3-none-any.whl (346 kB)
|████████████████████████████████| 346 kB 10.4 MB/s
Collecting spoon==2.27.0
Downloading spoon-2.27.0-py2.py3-none-any.whl (312 kB)
|████████████████████████████████| 312 kB 19.2 MB/s
Collecting cup>=1.6.0
Downloading cup-3.22.0-py2.py3-none-any.whl (397 kB)
|████████████████████████████████| 397 kB 28.2 MB/s
INFO: pip is looking at multiple versions of this package to determine
which version is compatible with other requirements.
This could take a while.
Downloading cup-3.21.0-py2.py3-none-any.whl (395 kB)
|████████████████████████████████| 395 kB 27.0 MB/s
Downloading cup-3.20.0-py2.py3-none-any.whl (394 kB)
|████████████████████████████████| 394 kB 24.4 MB/s
Downloading cup-3.19.1-py2.py3-none-any.whl (394 kB)
|████████████████████████████████| 394 kB 21.3 MB/s
Downloading cup-3.19.0-py2.py3-none-any.whl (394 kB)
|████████████████████████████████| 394 kB 26.2 MB/s
Downloading cup-3.18.0-py2.py3-none-any.whl (393 kB)
|████████████████████████████████| 393 kB 22.1 MB/s
Downloading cup-3.17.0-py2.py3-none-any.whl (382 kB)
|████████████████████████████████| 382 kB 23.8 MB/s
Downloading cup-3.16.0-py2.py3-none-any.whl (376 kB)
|████████████████████████████████| 376 kB 27.5 MB/s
Downloading cup-3.15.1-py2.py3-none-any.whl (385 kB)
|████████████████████████████████| 385 kB 30.4 MB/s
INFO: pip is looking at multiple versions of this package to determine
which version is compatible with other requirements.
This could take a while.
Downloading cup-3.15.0-py2.py3-none-any.whl (378 kB)
|████████████████████████████████| 378 kB 21.4 MB/s
Downloading cup-3.14.0-py2.py3-none-any.whl (372 kB)
|████████████████████████████████| 372 kB 21.1 MB/s
これらの複数の Downloading cup-{version} 行は、pip が依存関係解決中に選択をバックトラッキングしていることを示しています。
pip が依存関係解決中にバックトラッキングを開始すると、再検討する選択の数と必要な計算量がわかりません。
ユーザーにとって、これは、pip がバックトラッキングを開始すると完了するまでに時間がかかる可能性があることを意味します。パッケージに多くのバージョンがある場合、適切な候補に到達するのに時間がかかる可能性があります。時間は、パッケージのサイズ、pip が試行する必要があるバージョンの数、その他のさまざまな要因によって異なります。
バックトラッキングは、新しいパッケージのインストールによって既存のインストール済みパッケージが誤って破損するリスクを軽減し、環境が混乱するリスクを軽減します。そのためには、pip は、パッケージのどのバージョンがインストールするのに適した候補であるかを判断するために、より多くの作業を行う必要があります。
バックトラッキングを軽減するための可能性のある方法¶
pip が依存関係解決中に過度にバックトラッキングしている状況に対する万能な解決策はありません。ただし、pip がバックトラックする程度を軽減する方法があります。これらのアプローチのほとんどは、ある程度の試行錯誤が必要です。
pip がバックトラッキングを完了できるようにする¶
ほとんどの場合、pip はバックトラッキングプロセスを正常に完了します。完了するまでに非常に時間がかかる可能性があるため、これが好ましいオプションではない場合があります。
ただし、pip が互換性のあるバージョンのセットを見つけることができない可能性があります。この場合、pip は必要なすべての可能な組み合わせを試行し、互換性のあるセットがないことを判断します。
待たずに済ませたい場合は、pip を中断 (Ctrl+c) して、以下に示す方法を試すことができます。
pip が試行するバージョンの数を減らす¶
通常、pip がバックトラッキングしているパッケージ(上記の例では cup)に制約を追加することをお勧めします。
次のようなことを試すことができます。
$ python -m pip install tea "cup >= 3.13"
$ python -m pip install tea "cup >= 3.13"
C:> py -m pip install tea "cup >= 3.13"
これにより、試行する cup のバージョンの数が減り、pip のインストールにかかる時間が短縮される可能性があります。
追加された制約が間違っている可能性があります。この場合、検索空間が縮小されるため、pip は競合の原因をより迅速に特定してユーザーに提示することが容易になります。他の競合のために、pip が別のパッケージでバックトラッキングすることもあります。
制約ファイルまたはロックファイルを使用する¶
このオプションは、前のセクションの拡張です。ユーザーは、インストールしようとしているパッケージを検査する方法を知っている必要があります。
インストールしようとしているパッケージ
パッケージのリリース頻度と互換性ポリシー
過去のバージョンのリリースノートと変更ログ
デプロイメント中に、各パッケージの依存関係ごとに、正確なパッケージ名とバージョン番号を指定したロックファイルを作成できます。pip-tools を使用して作成できます。
これは、「作業」が開発プロセスで一度行われることを意味するため、デプロイメント中に依存関係解決を実行する必要がなくなります。
依存関係の競合の対処¶
このセクションでは、依存関係の競合によりpipが指定したパッケージをインストールできないResolutionImpossibleエラーが発生したpipユーザー向けの、実践的な解決策を紹介します。
エラーメッセージの理解¶
ResolutionImpossibleエラーが発生した場合、次のようなメッセージが表示されることがあります。
$ python -m pip install package_coffee==0.44.1 package_tea==4.3.0
[regular pip output]
ERROR: Cannot install package_coffee==0.44.1 and package_tea==4.3.0 because these package versions have conflicting dependencies.
The conflict is caused by:
package_coffee 0.44.1 depends on package_water<3.0.0,>=2.4.2
package_tea 4.3.0 depends on package_water==2.3.1
$ python -m pip install package_coffee==0.44.1 package_tea==4.3.0
[regular pip output]
ERROR: Cannot install package_coffee==0.44.1 and package_tea==4.3.0 because these package versions have conflicting dependencies.
The conflict is caused by:
package_coffee 0.44.1 depends on package_water<3.0.0,>=2.4.2
package_tea 4.3.0 depends on package_water==2.3.1
C:> py -m pip install package_coffee==0.44.1 package_tea==4.3.0
[regular pip output]
ERROR: Cannot install package_coffee==0.44.1 and package_tea==4.3.0 because these package versions have conflicting dependencies.
The conflict is caused by:
package_coffee 0.44.1 depends on package_water<3.0.0,>=2.4.2
package_tea 4.3.0 depends on package_water==2.3.1
この例では、それぞれが同じパッケージ(package_water)の異なるバージョンに依存しているため、pipは要求されたパッケージをインストールできません。
package_coffeeバージョン0.44.1は、3.0.0未満、2.4.2以上 のpackage_waterバージョンに依存しています。package_teaバージョン4.3.0は、package_waterのバージョン2.3.1に依存しています。
これらのメッセージは、必要なバージョンを指定するために一般的に理解されている比較演算子(例:< または >)を使用しているため、理解しやすい場合もあります。
しかし、Pythonのパッケージングでは、パッケージバージョンの指定方法として、より複雑な方法もサポートされています(例:~= または *)。
演算子 |
説明 |
例 |
|---|---|---|
|
指定されたバージョンより大きい任意のバージョン。 |
|
|
指定されたバージョンより小さい任意のバージョン。 |
|
|
指定されたバージョン以下の任意のバージョン。 |
|
|
指定されたバージョン以上の任意のバージョン。 |
|
|
指定されたバージョンと完全に一致するバージョン。 |
|
|
指定されたバージョンと等しくない任意のバージョン。 |
|
|
互換性のある¹バージョン。 |
|
|
バージョン番号の最後に使用して、「すべて」を表すことができます。 |
|
¹ 互換性のあるバージョンとは、最後のセグメントのみが異なる上位バージョンです。~=3.1.2 は >=3.1.2, ==3.1.* と同等です。~=3.1 は >=3.1, ==3.* と同等です。
サポートされている比較演算子の詳細な仕様については、PEP 440を参照してください。
考えられる解決策¶
エラーへの解決策は、個々のユースケースによって異なります。いくつかの解決策を試してみてください。
最上位の要件の監査¶
まず、プロジェクトを監査し、不要になったり古くなった要件(例:setup.pyまたはrequirements.txtファイル)を削除することが役立ちます。これらを削除することで、依存関係ツリーの複雑さが大幅に軽減され、競合が発生する可能性が低くなります。
最上位の要件の緩和¶
場合によっては、パッケージのバージョンを厳密に指定しすぎたために、pipにインストールを要求したパッケージが互換性がない場合があります。
最初の例では、package_coffeeとpackage_teaの両方が、特定のバージョン(package_coffee==0.44.1 package_tea==4.3.0)を使用するように固定されています。
package_waterの同じバージョンに依存するpackage_coffeeとpackage_teaの両方のバージョンを見つけるには、次のようなことを検討できます。
インストールするパッケージの範囲を緩める(例:
pip install "package_coffee>0.44.*" "package_tea>4.0.0")バージョン指定子を完全に削除して、
package_coffeeとpackage_teaの任意のバージョンをpipにインストールさせる(例:pip install package_coffee package_tea)
2番目の場合、pipは自動的にpackage_waterの同じバージョンに依存するpackage_coffeeとpackage_teaの両方のバージョンを見つけ、インストールします。
package_coffee 0.44.1(package_water 2.6.1に依存)package_tea 4.4.3(これもpackage_water 2.6.1に依存)
あるパッケージを別のパッケージよりも優先したい場合は、より重要なパッケージのみにバージョン指定子を追加できます。
$ python -m pip install package_coffee==0.44.1 package_tea
$ python -m pip install package_coffee==0.44.1 package_tea
C:> py -m pip install package_coffee==0.44.1 package_tea
これにより、次のようになります。
package_coffee 0.44.1(package_water 2.6.1に依存)package_tea 4.4.3(これもpackage_water 2.6.1に依存)
問題が解決したら、必要に応じて互換性のあるパッケージバージョンを再度固定できます。
依存関係の要件の緩和¶
上記のように、必要なパッケージのバージョンを緩めることで競合を解決できない場合は、依存関係で問題を修正するために、次を試すことができます。
パッケージのメンテナーに、彼らの依存関係を緩めるよう依頼する
パッケージをフォークし、自分で依存関係を緩める
警告
自分でパッケージをフォークすることを選択した場合、パッケージのメンテナーが提供するサポートを放棄することになります。自己責任で進めてください!
すべての要件が適切だが、解決策が存在しない¶
競合しないパッケージバージョンの組み合わせを見つけることが不可能な場合があります。依存関係の地獄へようこそ。
この状況では、次のようなことを検討できます。
プロジェクトで許容できる場合は、代替パッケージを使用します。Awesome Pythonで同様のパッケージを参照してください。
(例:モノリシックなコードベースをより小さなピースに分割することで)依存関係の数を減らすために、プロジェクトをリファクタリングします。
ヘルプの入手¶
上記の提案がどれも機能しない場合は、次の場所でヘルプを求めることをお勧めします。
ヘルプの求め方については、「“How do I ask a good question?”」を参照してください。
残念ながら、pipチームは個々の依存関係の競合エラーに対するサポートを提供できません。pipの問題トラッカーでチケットを開くのは、問題がpipのバグを明らかにしていると確信している場合にのみ行ってください。