PEP 704 – 規定套件安裝程式預設必須使用虛擬環境
- 作者:
- Pradyun Gedam <pradyunsg at gmail.com>
- 贊助人:
- Brett Cannon <brett at python.org>
- PEP 委託人:
- Paul Moore <p.f.moore at gmail.com>
- 討論於:
- Discourse 討論串
- 狀態:
- 已撤回
- 類型:
- 標準軌跡 (Standards Track)
- 主題:
- 套件封裝 (Packaging)
- 建立日期:
- 2023年1月16日
- 公告歷史:
- 2023年1月16日
摘要
此 PEP 建議 pip 等套件安裝程式在 Python 3.13+ 版本中,預設要求使用虛擬環境。
PEP 撤回
在此 PEP 的討論過程中,顯而易見的是,pip 的使用者體驗(UX)變更並不像提案中所述受 PEP 控制。同時也清楚的是,有大量使用者依賴於混合使用 pip 管理的依賴項與其他工具管理的依賴項(最顯著的情況是使用 Conda 時)。
此外,提議變更所帶來的大部分好處,都可以透過 PEP 668(在撰寫本文時已接受並實作)來實現。它讓 Python 解譯器的重新分發者能夠控制是否要求使用者必須使用虛擬環境、向使用者呈現什麼訊息,以及該變更應如何對其使用者逐步推行。
由於使用 pip 強制執行虛擬環境是本 PEP 的主要焦點,因此撤回本 PEP 比將其重新聚焦於其他主題更為合適。
未來若有 PEP 來解決虛擬環境命名慣例的問題/爭議仍是適當的,但任何此類嘗試都值得作為一個新的 PEP 重新開始,並專注於建立此類慣例的好處,而非強制執行它。
動機
Python 虛擬環境是 Python 開發流程中不可或缺的一部分。然而,由於它們是「選擇性加入(opt-in)」的功能,因此需要額外的努力,並要求使用者二選一:
- 採取明確步驟來啟用/停用虛擬環境
- 使用
<path-to-venv>/<bin-path>/<executable>來執行檔案
對於新使用者來說,不使用虛擬環境時,事情看起來運作正常——直到出問題為止。此外,在不同平台上啟用虛擬環境的語法和機制略有不同。這使得虛擬環境的入門變得複雜,因為現在必須解釋虛擬環境為何有用及其相關背景,才能證明在工作流程中增加額外步驟是合理的。
這也創造了犯錯的空間,因為使用者在執行像 pip 這樣的安裝程式前,需要記得啟用虛擬環境,或對安裝程式進行報錯配置。在某些 Linux 發行版上,忘記這樣做可能會導致安裝程式修改作業系統所擁有的檔案(對於選擇按照 PEP 668 標記其環境的發行版,此問題已得到部分緩解)。
原理
將像 pip 這樣的安裝程式預設行為更改為要求啟用虛擬環境將會:
- 使新使用者更容易開始使用 Python(因為有一致的體驗,且虛擬環境被理解為必須使用的東西)
- 預設降低所有使用者發生意外安裝問題的可能性(透過在未使用虛擬環境時明確發出警示)。
建立一個將虛擬環境放在目錄樹中名為 .venv 的目錄下的慣例,消除了常見流程中的一個決策點,並在生態系統中建立了一個明確的規範。
規範
預設要求使用虛擬環境
當使用者在沒有啟用虛擬環境的情況下執行安裝程式時,安裝程式「應該(SHOULD)」列印錯誤訊息並以非零錯誤碼結束。
錯誤訊息「應該」告知使用者需要虛擬環境,「應該」提供特定 shell 的指令說明如何建立及啟用名為 .venv 的虛擬環境,且「應該」提供一個連結到說明如何建立及啟用虛擬環境的說明文件頁面。
詳見 實作說明。
選擇不使用虛擬環境
安裝程式「應該」也提供一個明確的選擇加入(opt-in)機制來停用此要求,允許最終使用者在虛擬環境之外使用。如果安裝程式未提供此功能,則「應該」在錯誤訊息和說明文件中提到這一點。
變更的一致時間表
安裝程式「可以(MAY)」選擇在任何 Python 版本上實作此預設行為,但「應該」在 Python 3.13 或更新版本上實作。
回溯相容性
此 PEP 與使用者在虛擬環境之外使用安裝程式的工作流程不回溯相容。此類使用者將收到錯誤訊息,並需要:
- 明確選擇在虛擬環境之外執行安裝程式,或
- 建立並使用虛擬環境
已經在使用虛擬環境的使用者將不受此變更的影響。
工作流程工具(在底層為使用者管理虛擬環境的工具)不應受到影響,因為它們應該已經在使用虛擬環境來執行安裝程式。
安全性影響
此 PEP 沒有引入任何新的安全隱患。
如何教學
此 PEP 要求新使用者在開始使用 Python 套件之前必須建立並使用虛擬環境。然而,這是一項最佳實踐,誠如 Python 套件使用者指南中「如何安裝 Python 套件的基礎知識」一節所展示的,該節在討論使用 pip 之前就解釋了什麼是虛擬環境及其用途。
參考實作
此 PEP 沒有參考實作。然而,提議的行為在 pip 中已大致實作,且可以透過將環境變數 PIP_REQUIRE_VENV 設定為 1 來啟用。(若不設定,則為提議的選擇加入行為,即安裝時不要求虛擬環境。)
實作筆記
偵測啟用的虛擬環境
正如在 PEP 668 中討論的,穩健偵測虛擬環境的邏輯大約如下:
def is_virtual_environment():
return sys.base_prefix != sys.prefix or hasattr(sys, "real_prefix")
使用虛擬環境的說明文件
套件安裝程式應在錯誤訊息中提供指向說明文件頁面的連結。
理想情況下,此類說明文件頁面將解釋什麼是虛擬環境、為什麼需要虛擬環境,以及如何使用 venv 建立和啟用虛擬環境。它應包含針對最常見的 shell 和平台的指令。
此類說明文件頁面應在 Python 套件使用者指南中提供,以減少不同安裝程式在涵蓋此主題時重複投入的努力。
否決的想法
不指定虛擬環境目錄的名稱
為虛擬環境目錄使用一致的名稱非常重要,原因如下:
- 這使得使用者更容易找到虛擬環境目錄並啟用它。
- 它為新使用者消除了一個決策點,因為他們不需要為虛擬環境目錄決定名稱。
- 它在生態系統中建立了一個明確的規範,使使用者更容易找到文件。
- 它確保了跨不同工具的一致性,使得錯誤訊息的差異不會混淆使用者。
為虛擬環境目錄使用不同的名稱
就功能而言,只要有一個單一且一致的建議,目錄名稱並不重要。
之所以選擇 .venv 這個名稱,是因為它:
- 不與任何有效的 Python 匯入名稱衝突
- 不與標準程式庫中的
venv模組衝突 - 在 Python 社群中已有現成的使用案例
- 在常見的文字編輯器中有自動偵測支援
- 在常見的鍵盤佈局中不需組合鍵即可輸入
不將工具行為與 Python 版本耦合
此 PEP 在安裝程式的行為與 Python 版本之間建立了耦合。
這已經是安裝工具行為變更所使用的一種推行機制。例如,Python 3.11 上的 pip 將使用 importlib.metadata 而非 pkg_resources 來解析/獲取套件元數據,並使用 sysconfig 而非 distutils.sysconfig 來獲取解壓 wheel 的路徑。
與這些案例的不同之處在於,那些變更對最終使用者來說大致上是透明的。而此 PEP 提議的行為變更對最終使用者而言並非透明,且需要他們採取行動。
這樣做的主要好處是,它允許重新分發者及時針對新的 Python 版本調整其工具,並為整個生態系統的變更提供一個明確且一致的時間點。它還為預設行為何時會一致要求虛擬環境設定了明確的期限(一旦 Python 3.12 結束生命週期)。
這種方法的主要問題在於,它在使用者升級到新的 Python 版本時強制執行行為變更,這可能會阻礙新 Python 版本的採用。然而,這對於現有使用者來說是一種遷移/升級,而且普遍預期遷移/升級時會需要「某些」變更。
此 PEP 的作者認為,在整個生態系統中帶有期限地一致應用此舉所帶來的好處,超過了在使用者升級時強制執行最佳實踐的缺點。
待決問題
無。
版權
本文件已進入公有領域或遵循 CC0-1.0-Universal 授權,以較寬鬆者為準。
來源:https://github.com/python/peps/blob/main/peps/pep-0704.rst
最後修改時間:2025-02-01 08:55:40 GMT