相依性解析¶
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"
這會減少 pip 嘗試的 cup
版本數量,並可能縮短 pip 的安裝時間。
新增的限制條件有可能是錯誤的。當這發生時,縮小的搜尋空間讓 pip 能夠更快速地找出衝突原因,並將其呈現給使用者。這也可能導致 pip 由於其他衝突而回溯其他套件。
使用限制條件檔案或鎖定檔¶
這個選項是前一段的延伸。它需要使用者知道如何檢查
他們試著安裝的套件
套件發佈頻率和相容性政策
他們從舊版本中的發佈說明和變更日誌
在佈署過程中,你可以建立一個鎖定檔,指出那個套件中每個相依套件的明確套件和版本號碼。你可以使用 pip-tools 建立它。
這表示「工作」在開發過程中只會執行一次,因此可以避免在佈署時執行相依項性解析。
處理相依項性衝突¶
這段提供實作建議給遇到 ResolutionImpossible
錯誤的 pip 使用者,其中 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
在此範例中,pip 無法安裝你要求的套件,因為它們各自相依於同一個套件(package_water
)的不同版本
package_coffee
版本0.44.1
相依於小於3.0.0
但大於或等於2.4.2
的package_water
版本package_tea
第4.3.0
版依賴package_water
第2.3.1
版
有時這些訊息易於閱讀,因為它們使用常見的比較運算子來指定必要的版本(例如 <
或 >
)。
不過,Python 封裝也支援一些比較複雜的方法來指定套件版本(例如 ~=
或 *
)
運算子 |
描述 |
範例 |
---|---|---|
|
大於指定版本的任何版本。 |
|
|
小於指定版本的任何版本。 |
|
|
小於或等於指定版本的任何版本。 |
|
|
大於或等於指定版本的任何版本。 |
|
|
等於指定版本的任何版本。 |
|
|
不等於指定版本的任何版本。 |
|
|
任何相容1版本。 |
|
|
可以在版本號碼的結尾使用,代表所有。 |
|
1 相容版本是僅在最後一段不同的更高版本。 ~=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_coffee
和 package_tea
依賴相同版本的 package_water
的版本,您可以考慮
放寬您準備安裝的套件範圍(例如
pip install "package_coffee>0.44.*" "package_tea>4.0.0"
)要求 pip 安裝 任何 版本的
package_coffee
和package_tea
,方法是完全移除版本指定符(例如pip install package_coffee package_tea
)
在第二個案例中,pip 會自動找出 package_coffee
和 package_tea
依賴相同版本的 package_water
的版本,安裝
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
現在您已解決問題,可以視需要重新固定相容的套件版本。
放寬您依賴項的要求¶
假設您無法透過放寬您需要的套件版本 (如前述) 來解決衝突,您可以嘗試透過以下方式來修正您依賴項上的問題:
請求套件維護者放寬其依賴項
自行分叉套件,同時放寬依賴項
警告
如果您選擇自行分叉套件,您將不再能獲得套件維護者提供的任何支援。請自行承擔風險!
所有需求皆適當,但找不到解決方案¶
有時確實找不到不會造成衝突的套件版本組合。歡迎進入 依賴性地獄。
在這種情況下,您可以考慮
使用替代套件,如果您的專案可以接受。請參閱 Python 的類似套件。
重構您的專案以減少依賴項的數量 (例如,將單一程式碼庫分拆為較小的區塊)。
尋求協助¶
如果上述建議對您沒有幫助,我們建議您在以下地方尋求協助
請參閱 “如何提出好的問題?” 以瞭解尋求協助的訣竅。
很遺憾,pip 團隊無法對個別依賴項衝突錯誤提供支援。如果您相信自己的問題揭露了 pip 中的錯誤,請僅在 pip 的問題追蹤器 上開啟票證。