為什么使用 apt 安裝的 python 第三方包版本會出現滯后現象?
在 ubuntu 22.04 系統中,用戶可能會發現通過 apt 安裝的 Python 第三方包版本相對較舊。這種情況在處理 Let’s Encrypt 證書時尤為明顯。例如,執行 sudo apt install certbot python3-certbot-nginx 后,使用 certbot 命令時,可能會遇到版本不兼容的錯誤。
例如,用戶在執行以下命令時:
sudo certbot certonly --manual --preferred-challenges dns -d xxxxx.cn -d *.xxxxx.cn
可能會看到類似如下的錯誤信息:
Traceback (most recent call last): File "/usr/lib/python3/dist-packages/requests_toolbelt/_compat.py", line 48, in <module> from requests.packages.urllib3.contrib import appengine as gaecontrib ImportError: cannot import name 'appengine' from 'requests.packages.urllib3.contrib' (/usr/local/lib/python3.10/dist-packages/urllib3/contrib/__init__.py) ...</module>
查看 certbot 的版本:
立即學習“Python免費學習筆記(深入)”;
pon@aliyun2core2GB:~$ pip show certbot Name: certbot Version: 1.21.0 Summary: ACME client ...
發現 certbot 版本為 1.21.0,這是一個相對較舊的版本。
為什么會出現這種情況呢?Ubuntu 是如何管理 apt 中可下載的 Python 第三方包版本的呢?通常情況下,apt 應該自動解決依賴問題并下載一個兼容的最新版本。
實際上,經過測試發現 certbot 1.21.0 版本本身是正常工作的,并不存在不兼容的問題。問題的關鍵在于,在使用 apt 安裝 certbot 之前,可能已經使用 pip 安裝了 urllib3 這個依賴包。
查看錯誤信息,可以看到 urllib3 的文件路徑位于 /usr/local/lib/python3.10/dist-packages,而 certbot 的文件路徑位于 /usr/lib/python3/dist-packages。這是因為通過 apt install python-xxx 安裝的包文件存放在 /usr/lib/python3/dist-packages,而通過 sudo pip install xxx 安裝的包文件存放在 /usr/local/lib/python3.10/dist-packages。
Python 在加載包時有目錄優先級,優先級如下:
- /usr/local/lib/python3.10/dist-packages
- /usr/lib/python3/dist-packages(優先級最低)
因此,當 certbot 嘗試導入 urllib3 時,會優先加載 /usr/local/lib/python3.10/dist-packages 中的 urllib3,導致版本沖突。
解決這個問題的方法有以下幾種:
- 避免在系統中使用 pip 安裝第三方包,只使用 apt 進行包管理。
- 使用虛擬環境,這樣可以避免系統包與用戶安裝的包之間的沖突。
- 只使用 pip 管理包,但需要確保不會與系統包產生沖突。
通過了解這些信息,用戶可以更好地管理和解決使用 apt 安裝的 Python 第三方包版本滯后問題。