PEP 413 – 更快地演進 Python 標準庫
- 作者:
- Alyssa Coghlan <ncoghlan at gmail.com>
- 狀態:
- 已撤回
- 型別:
- 流程
- 建立日期:
- 2012年2月24日
- 釋出歷史:
- 2012年2月24日,2012年2月25日
PEP 撤回
隨著 PEP 453 被接受,意味著 pip 將預設提供給大多數新的 Python 使用者,這有望減輕在模組尚未足夠成熟之前就將其新增到標準庫的壓力。
過去幾年,標準庫包與 Python 包索引(PyPI)中支援舊版本 Python 的等效包同時存在的模型使用率也越來越高。
鑑於這兩個發展以及在 Python 3.4 釋出週期中的參與度,PEP 作者認為現在不再適合對標準庫的開發流程進行如此根本性的改變。
摘要
本 PEP 提議採用一種獨立的標準庫版本控制方案(獨立於現有語言版本控制方案,但與之關聯),該方案允許 Python 標準庫加速釋出,同時保持(甚至放緩)核心語言定義當前的變化速度。
與 PEP 407 類似,它旨在調整當前在衡量變化(允許更廣泛的社群有時間適應)和跟上比當前釋出週期更能快速處理的外部影響(尤其是與 Web 技術相關的標準庫元素)之間的平衡。
然而,它在目標上比 PEP 407 更保守,尋求將開發速度的加快限制在內建和標準庫介面上,而不影響其他元素的變化速度,例如語言語法、版本編號以及 CPython 二進位制 API 和位元組碼格式。
基本原理
引用 PEP 407 的摘要:
為開源專案找到釋出週期是一個精妙的練習,需要管理相互矛盾的約束:開發者人力、釋出管理志願者的可用性、使用者和第三方打包者的維護便利性、新功能(和行為變更)的快速可用性、在不引入新功能或行為變更的情況下獲取錯誤修復的可用性。當前的釋出週期傾向於保守。它適合那些重視穩定性而非響應能力的人。本 PEP 試圖在保持 Python 標誌性的穩定性同時,透過引入長期支援版本(LTS)的概念,提供更流暢的功能釋出。
我同意 PEP 407 作者的觀點,即當前標準庫的釋出週期太慢,無法有效應對某些關鍵程式設計領域(特別是 Web 協議和相關技術,包括資料庫、模板和序列化格式)的變化速度。
但是,我寫了這份競爭性的 PEP,因為我相信 PEP 407 中提出的每 6 個月釋出一次完全、可能不相容二進位制的 CPython 的方法,給更廣泛的 Python 生態系統帶來了過大的負擔。
在當前的 CPython 釋出週期下,關鍵二進位制擴充套件的發行商通常會支援 Python 版本,即使 CPython 的分支已經進入“僅限安全修復”模式(例如,Twisted 目前提供 2.5、2.6 和 2.7 的二進位制版本,NumPy 和 SciPy 支援這三個版本以及 3.1 和 3.2,PyGame 添加了 2.4 的二進位制版本,wxPython 為 2.6 和 2.7 提供 32 位和 64 位二進位制版本等)。
如果 CPython 的釋出速度增加兩倍(或更多),這些庫的開發者(其中許多比 CPython 的資源更緊張)將面臨一個令人不快的選擇:要麼自己採用更快的釋出週期(PyGame 可能需要多達 18 個併發二進位制版本!),要麼更快地放棄舊的 Python 版本,或者告訴使用者堅持使用 CPython LTS 版本(這樣一來就完全失去了加快 CPython 釋出週期的初衷)。
同樣,許多 Python 的支援工具(例如語法高亮器)可能需要很長時間才能跟上語言級別的變化。
在文化層面,Python 社群也習慣了 Python 版本號的特定含義——它們與棄用週期、支援週期等各種事物相關聯。PEP 407 提議將所有集體知識一掃而空,而沒有提供有說服力的理由說明為什麼這種行動是真正必要的(除了也許讓 CPython 核心開發者的生活稍微輕鬆一些,而犧牲了其他所有人)。
然而,如果我們回到加快變化速度的主要原因(即更及時地支援 Web 協議和相關技術),我們可以注意到這些只需要標準庫的更改。這意味著許多(甚至可能是大多數)對更廣泛社群的負面影響可以透過明確限制 CPython 的哪些部分受新發布週期的影響,並允許其他部分以當前更平穩的速度發展來避免。
提案
本 PEP 提議引入一種新的 CPython 釋出型別:“標準庫釋出”。與 PEP 407 一樣,這將使 CPython 擁有 3 種釋出型別:
- 語言釋出:“x.y.0”
- 維護髮布:“x.y.z”(其中 z > 0)
- 標準庫釋出:“x.y (xy.z)”(其中 z > 0)
在此方案下,一個不加限定的版本引用(例如“3.3”)將始終指向最新的相應語言或維護版本。它絕不會被不加限定地用來指代標準庫釋出(至少,python-dev 不會這樣做——顯然,我們只能樹立榜樣,而不能強迫 Python 生態系統的其餘部分遵循)。
語言釋出將繼續像現在一樣,作為 Python 語言定義的新版本,以及 CPython 直譯器和 Python 標準庫的新版本。因此,語言釋出可能包含以下任何或所有更改:
- 新的語言語法
- 新的標準庫更改(見下文)
- 新的棄用警告
- 移除先前已棄用的功能
- 發出的位元組碼的更改
- AST 的更改
- 編譯工具鏈的任何其他重大更改
- 核心直譯器 eval 迴圈的更改
- C ABI 的二進位制不相容更改(儘管 PEP 384 穩定 ABI 仍須保留)
- 錯誤修復
維護髮布也將繼續像今天一樣,嚴格限制為相應語言版本的錯誤修復。不允許有新功能或重大的內部更改。
新的標準庫釋出將與每個維護髮布並行進行,並將用新的版本識別符號來限定,以記錄標準庫的版本。標準庫釋出可能包括以下更改:
- 純 Python 模組中的新功能
- C 擴充套件模組中的新功能(受 PEP 399 相容性要求約束)
- 語言內建函式中的新功能(前提是 C ABI 保持不變)
- 相應維護版本的錯誤修復
標準庫版本識別符號是透過將 Python 語言釋出的major和minor版本號組合成一個兩位數,然後附加一個順序的標準庫版本識別符號來構建的。
釋出週期
當建立維護版本時,將在 python.org 上實際釋出兩個新的 Python 版本(以 2013 年 2 月計劃的第一個 3.3 維護版本為例):
3.3.1 # Maintenance release
3.3 (33.1) # Standard library release
又過了 6 個月,下一個 3.3 維護版本將再次伴隨新的標準庫釋出。
3.3.2 # Maintenance release
3.3 (33.2) # Standard library release
同樣,標準庫釋出將與之前的語言釋出二進位制相容,僅在 Python 層面提供額外功能。
最後,在 3.3 釋出 18 個月後,一個新的語言版本將與最終的 3.3 維護和標準庫釋出大致在同一時間釋出。
3.3.3 # Maintenance release
3.3 (33.3) # Standard library release
3.4.0 # Language release
3.4 的釋出週期隨後將遵循與 3.3 類似的模式。
3.4.1 # Maintenance release
3.4 (34.1) # Standard library release
3.4.2 # Maintenance release
3.4 (34.2) # Standard library release
3.4.3 # Maintenance release
3.4 (34.3) # Standard library release
3.5.0 # Language release
程式化版本標識
為了以程式設計方式暴露新的版本詳細資訊,本 PEP 提議新增一個新的 sys.stdlib_info 屬性,該屬性記錄了標準庫版本高於底層直譯器版本的資訊。以最初的 Python 3.3 版本為例:
sys.stdlib_info(python=33, version=0, releaselevel='final', serial=0)
這些資訊也將包含在 sys.version 字串中。
Python 3.3.0 (33.0, default, Feb 17 2012, 23:03:41)
[GCC 4.6.1]
安全修復和其他“週期外”釋出
對於維護版本,處理週期外發布(例如,修復安全問題或解決新版本的關鍵錯誤)的流程與現在相同:遞增次要版本號,然後釋出一個包含所需錯誤修復以及自上一版本以來已提交的任何其他錯誤修復的新版本。
對於標準庫釋出,流程基本相同,但相應的“有什麼新內容?”文件可能需要進行一些整理(因為標準庫釋出可能包含新功能,而不僅僅是錯誤修復)。
使用者場景
上面提出的版本控制方案是基於如果採用該方案可能會遇到的多個使用者場景。在每種情況下,場景都針對現狀(即緩慢的釋出週期)、本 PEP 中的版本控制方案以及 PEP 407 中提出的自由的次要版本號方案進行了描述。
為了給出結局,使用單獨版本號的要點是,對於幾乎所有場景,重要的數字是語言版本,而不是標準庫版本。大多數使用者甚至不需要關心標準庫版本號的存在。在確定了需要它的兩個場景中,將其作為一個單獨的數字提供實際上比將兩種不同型別的數字嵌入到單個序列中,然後將該統一序列中的某些數字標記為特殊數字更清晰、更明確。
新手使用者,2013年3月從python.org下載Python
現狀:必須在 3.3 和 2.7 之間選擇
本 PEP:必須在 3.3 (33.1)、3.3 和 2.7 之間選擇。
PEP 407:必須在 3.4、3.3 (LTS) 和 2.7 之間選擇。
結論:解釋長期支援版本的含義與解釋擬議的標準庫版本號的含義一樣複雜。我稱之為平局。
新手使用者,嘗試判斷第三方文件的更新程度
現狀:次要版本差異表示 18-24 個月的語言演進
本 PEP:語言核心與現狀相同,標準庫版本號表示 6 個月的標準庫演進。
PEP 407:次要版本差異表示 18-24 個月的語言演進,直到 3.3,此後為 6 個月的語言演進。
結論:由於語言變更和棄用對第三方文件的準確性可能比為標準庫新增新功能產生更大的影響,我將此稱為本 PEP 方案的勝利。
新手使用者,尋找擴充套件模組的二進位制釋出
現狀:查詢與正在執行的 Python 版本相對應的二進位制檔案。
本 PEP:與現狀相同。
PEP 407 (完整發布):與現狀相同,但相應的二進位制版本更有可能缺失(或者,如果存在,則必須在更多的替代選項中找到)。
PEP 407 (ABI 更新僅限於 LTS 版本):所有二進位制釋出頁面都需要告訴使用者 Python 3.3、3.4 和 3.5 都需要 3.3 的二進位制檔案。
結論:我稱之為本 PEP 方案的明顯勝利。與當前情況相比,沒有任何變化,因為在這種情況下,標準庫版本實際上是無關緊要的(只有二進位制擴充套件相容性才重要)。
Python 開發者,決定消除棄用警告的優先順序
現狀:觸發棄用警告的程式碼不能保證在次要版本號更高的 Python 版本上執行。
本 PEP:與現狀相同。
PEP 407:不明確,因為 PEP 目前沒有詳細說明。假設棄用週期與 LTS 版本相關聯,那麼升級到非 LTS 版本是安全的,但升級到下一個 LTS 版本可能需要避免已棄用的構造。
結論:本 PEP 方案的又一個明顯勝利,因為在這種情況下,標準庫版本再次無關緊要。
替代直譯器實現者,更新新功能
現狀:新 Python 版本 infrequent 地釋出,但它們是標準庫更新、核心語言定義和直譯器更改的混合體。
本 PEP:標準庫更新更容易整合,並且以一種清晰明確地與先前語言版本相容的形式更頻繁地提供。這意味著,一旦替代實現趕上 Python 3.3,它們在整合標準庫功能方面應該會更容易(尤其是純 Python 更改),只留下次要版本號更新作為需要更新其核心編譯和執行元件的唯一任務。
PEP 407 (完整發布):與現狀相同,但發生的頻率要高得多。
PEP 407 (語言更新僅限於 LTS 版本):不明確,因為 PEP 目前沒有詳細說明具體的發展策略。假設採用了 3.3 相容分支(如本 PEP 所建議),那麼結果將大致相同,但版本號訊號的清晰度會稍差一些(因為您需要檢查特定版本是否為 LTS 版本)。
結論:雖然不如之前的一些場景那樣清晰,但我仍然認為本 PEP 方案佔優。顯式優於隱式,本 PEP 方案在兩種不同型別的更新之間進行了清晰的區分,而不是在普通版本號上新增單獨的“LTS”標籤。標記特定版本為特殊版本對於與版本控制系統和相關自動化工具進行通訊非常有用,但對於向其他人類傳達資訊則是一個糟糕的方式。
Python 開發者,決定其最低版本依賴
現狀:查詢文件中的“版本新增”或“版本更改”標記,與 sys.version_info 進行對比。
本 PEP:查詢文件中的“版本新增”或“版本更改”標記。如果寫成裸 Python 版本,例如“3.3”,則與 sys.version_info 進行對比。如果帶有標準庫版本限定,例如“3.3 (33.1)”,則與 sys.stdlib_info 進行對比。
PEP 407:與現狀相同。
結論:本 PEP 中的方案實際上允許第三方庫更明確地說明其採用標準庫功能的速率。更保守的專案可能會將其依賴項固定到語言版本,並避免在標準庫版本中新增的功能。移動速度更快的專案可以改為宣告其對特定標準庫版本的依賴。然而,由於 PEP 407 確實具有保留現狀的優勢,因此我將此判給 PEP 407(儘管優勢微弱)。
Python 開發者,嘗試重現追蹤器中的問題
現狀:如果尚未提供,請詢問報告者他們正在使用哪個版本的 Python。這通常透過詢問互動式提示的前兩行顯示的內容或 sys.version 的值來完成。
本 PEP:與現狀相同(因為 sys.version 將更新為包含標準庫版本),但可能需要更多次(使用者知道足夠的資訊來宣告其 Python 版本,但這不足以重現故障)。
PEP 407:與現狀相同。
結論:又一個 PEP 407 的小幅優勢。新的標準庫版本是使用者在報告 Python 庫(或 Python 本身,在我們自己的跟蹤器上)的問題時可能需要提供給開發者的額外資訊。然而,透過將其包含在 sys.version 中,許多故障報告將已經包含它,並且如果需要,很容易請求。
CPython 釋出管理者,處理安全修復
現狀:建立一個包含安全修復和原始碼控制中任何其他錯誤修復的新維護版本。還為僅用於安全修復的分支建立原始碼版本。
本 PEP:對於維護分支,與現狀相同。還建立一個新的標準庫版本(可能包含新功能和安全修復)。對於安全分支,為前一個維護分支和標準庫更新分支建立原始碼版本。
PEP 407:對於維護和安全分支,與現狀相同,但處理非 LTS 版本的安全修復目前是一個開放性問題。
結論:在 PEP 407 更新以實際解決此場景之前,本 PEP 明顯佔優。
影響
對開發週期的影響
與 PEP 407 類似,本 PEP 將把新功能的交付分解成更離散的塊。語言釋出中不會一次性出現大量更改,而是每次語言釋出將僅限於 6 個月的標準庫更改,以及與新語法相關的任何更改。
對工作流程的影響
本 PEP 提議在正常工作流程中使用一個額外的分支。在 3.3 釋出後,將使用以下分支:
2.7 # Maintenance branch, no change
3.3 # Maintenance branch, as for 3.2
3.3-compat # New branch, backwards compatible changes
default # Language changes, standard library updates that depend on them
在處理新功能時,開發人員需要決定它是否是標準庫釋出的可接受更改。如果是,則應將其簽入 3.3-compat,然後合併到 default。否則,應直接簽入 default。
對在 3.3-compat 分支上進行的任何更改的“版本新增”和“版本更改”標記都需要用語言版本和標準庫版本進行標記。例如:“3.3 (33.1)”。
直接在 default 分支上進行的任何更改都將像往常一樣僅標記為“3.4”。
在 3.3-compat 分支正常開發將在 3.3 維護分支關閉時同時關閉。 3.3-compat 分支將保持開放狀態以進行安全修復,其時間與 3.3 維護分支相同。
對錯誤修復週期的影響
錯誤修復工作流程的影響與新功能工作流程的影響基本相同——在更改到達 default 分支之前,還有一個額外的分支需要透過。
如果在維護版本中發現關鍵錯誤,那麼將建立新的維護和標準庫版本來解決問題。版本號的最後一部分將為語言版本和標準庫版本遞增。
如果在不影響相關維護版本的情況下在標準庫版本中發現關鍵錯誤,那麼將只建立一個新的標準庫版本,並且只遞增標準庫的版本號。
請注意,在這些情況下,標準庫釋出可能包含其他功能,而不僅僅是錯誤修復。假設任何只關心接收錯誤修復而不混合新功能的人都已經嚴格依賴維護版本,而不是使用新的標準庫版本。
對社群的影響
PEP 407 在社群影響方面有以下說法:
重視穩定性的人只需同步 LTS 版本,根據擬議的數字,這將提供相似的支援週期(在持續時間和穩定性方面)。
我認為這個說法簡直是錯的。生活並非如此簡單。相反,第三方模組和框架的開發者將面臨支援新發布週期完整速度的二進位制更新的壓力,教師和書籍作者將收到關於他們只涵蓋“舊”版本 Python 的投訴(“你只用 3.3,最新的是 3.5!”),等等。
隨著次要版本號開始比過去快 3 倍,我認為語言穩定性的看法也會下降(無論這些觀點是否合理)。
我認為將加快變化速度的範圍限定在標準庫,並用單獨的版本號明確區分它,將極大地讓社群的其餘部分放心,不,我們沒有突然要求他們將自己的開發速度提高兩倍。相反,我們只會以 6 個月一次的增量釋出下一個語言版本的標準庫更新,而不是將它們推遲到下一個語言定義更新,即使是那些與先前釋出的 Python 版本向後相容的更改。
PEP 407 中列出的社群好處同樣適用於本 PEP,至少在標準庫方面是如此:
重視響應能力和新功能可用性(而不必承擔安裝 alpha 版本或 Mercurial 快照的風險)的人,將比目前從新發布週期中獲得更多價值。想要貢獻新功能或改進的人,將會更有動力去做,因為知道他們的貢獻將更快地提供給普通使用者。
如果更快的釋出週期鼓勵更多人專注於為標準庫做貢獻,而不是提出語言定義更改,我不認為這是一件壞事。
新聞更新的處理
有什麼新內容?
“有什麼新內容?”文件將被拆分成標準庫釋出和語言釋出。因此,在 3.3 釋出週期中,我們將看到:
- Python 3.3 有什麼新內容?
- Python 標準庫 33.1 有什麼新內容?
- Python 標準庫 33.2 有什麼新內容?
- Python 標準庫 33.3 有什麼新內容?
最後,我們將看到下一個語言版本:
- Python 3.4 有什麼新內容?
為了方便忽略標準庫釋出的使用者的利益,3.4 的“有什麼新內容?”將連結回 3.3 系列的標準庫釋出的“有什麼新內容?”文件。
NEWS
NEWS 檔案的合併衝突已經是件麻煩事了。由於本 PEP 提議在正常工作流程中引入額外的分支,解決這個問題變得更加重要。雖然 Mercurial 的 phases 在一定程度上可能有所幫助,但最好能完全消除這個問題。
Barry Warsaw 的一個建議是採用一種不衝突的、每個更改對應一個檔案的做法,類似於 Twisted 的做法 [2]。
鑑於 3.3.0 版本將使用當前手動更新的 NEWS 檔案,這種方法的一種可能佈局如下:
Misc/
NEWS # Now autogenerated from news_entries
news_entries/
3.3/
NEWS # Original 3.3 NEWS file
maint.1/ # Maintenance branch changes
core/
<news entries>
builtins/
<news entries>
extensions/
<news entries>
library/
<news entries>
documentation/
<news entries>
tests/
<news entries>
compat.1/ # Compatibility branch changes
builtins/
<news entries>
extensions/
<news entries>
library/
<news entries>
documentation/
<news entries>
tests/
<news entries>
# Add maint.2, compat.2 etc as releases are made
3.4/
core/
<news entries>
builtins/
<news entries>
extensions/
<news entries>
library/
<news entries>
documentation/
<news entries>
tests/
<news entries>
# Add maint.1, compat.1 etc as releases are made
將版本資訊放在目錄層次結構中並非嚴格必要(因為 NEWS 檔案生成器可以從版本歷史中獲取),但確實使得人類更容易保持不同版本的順序。
減少版本耦合的其他好處
放慢語言釋出週期
當前的釋出週期是在核心語言定義和 C 擴充套件 ABI 的穩定性需求,以及希望更快地將新功能(尤其是標準庫更新)交付給使用者的手中之間的折衷。
透過(在一定程度上)將標準庫釋出週期與核心語言定義釋出週期脫鉤,它提供了一個機會來實際放慢語言定義的變更速度。Python 3.2 的語言凍結期實際上將該週期放慢到了三年多(3.1:2009 年 6 月,3.3:2012 年 8 月),而沒有引起任何重大問題或抱怨。
上述 NEWS 檔案管理方案實際上是為了讓我們在標準庫釋出變得更頻繁的同時,能夠靈活地放慢語言釋出的節奏。
作為簡單示例,如果在 3.3 和 3.4 之間允許整整兩年,3.3 的釋出週期將如下所示:
3.2.4 # Maintenance release
3.3.0 # Language release
3.3.1 # Maintenance release
3.3 (33.1) # Standard library release
3.3.2 # Maintenance release
3.3 (33.2) # Standard library release
3.3.3 # Maintenance release
3.3 (33.3) # Standard library release
3.3.4 # Maintenance release
3.3 (33.4) # Standard library release
3.4.0 # Language release
擬議分支結構和 NEWS 條目佈局的優雅之處在於,這個決定實際上直到 3.4 計劃釋出日期前不久才需要做出。屆時,可以決定推遲 3.4 的釋出,並在 3.3.3 維護版本和 3.3 (33.3) 標準庫釋出後繼續開放 3.3 和 3.3-compat 分支,從而在該週期中新增另一個標準庫釋出。之後每 6 個月將提供另一個標準庫釋出或完整語言釋出的選項。
進一步加快標準庫開發的速度
如前一節所述,本 PEP 提出的方案的一個好處是它在很大程度上將語言釋出週期與標準庫釋出週期分離。標準庫可以每 3 個月更新一次,甚至每月更新一次,而不會對語言版本號或核心語言的感知穩定性產生任何後續影響。
雖然只要 Windows 和 Mac OS X 的二進位制安裝程式建立涉及多個手動步驟(包括手動測試),並且我們還沒有獨立的“<branch>-release”樹來接收已由穩定 buildbots 標記為良好的版本,這種開發速度就不切實際,但它仍然是一個在考慮提議的新版本控制方案時應牢記的標準:如果我們最終希望使標準庫釋出比每 6 個月更快怎麼辦?
如果這些實際問題得到解決,那麼本 PEP 中的獨立標準庫版本控制方案就可以處理。PEP 407 中提出的帶標記版本號的方法則不能(至少,沒有很多使用者混淆和不確定性的話)。
其他問題
為什麼不使用主版本號?
最簡單和最合乎邏輯的解決方案實際上是將 major.minor.micro 版本號對映到語言版本、stdlib 版本和維護版本。
與其釋出 Python 3.3.0,不如釋出 Python 4.0.0,釋出週期如下:
4.0.0 # Language release
4.0.1 # Maintenance release
4.1.0 # Standard library release
4.0.2 # Maintenance release
4.2.0 # Standard library release
4.0.3 # Maintenance release
4.3.0 # Standard library release
5.0.0 # Language release
然而,Python 2 -> Python 3 過渡的持續痛苦(以及諸如 python3 和 python2 符號連結以直接指向所需的釋出系列等變通方法)意味著出於歷史原因,這個簡單的選項是不可行的。
這個簡單方法可以奏效的一種方式是,將當前的 major 和 minor 版本號直接合併為一個兩位數的 major 版本號:
33.0.0 # Language release
33.0.1 # Maintenance release
33.1.0 # Standard library release
33.0.2 # Maintenance release
33.2.0 # Standard library release
33.0.3 # Maintenance release
33.3.0 # Standard library release
34.0.0 # Language release
為什麼不使用四位版本號?
另一個簡單的版本控制方案只是在現有版本控制方案中新增一個“標準庫”版本:
3.3.0.0 # Language release
3.3.0.1 # Maintenance release
3.3.1.0 # Standard library release
3.3.0.2 # Maintenance release
3.3.2.0 # Standard library release
3.3.0.3 # Maintenance release
3.3.3.0 # Standard library release
3.4.0.0 # Language release
但是,由於 sys.version_info 結構的向後相容性限制,該方案不可行。
為什麼不使用基於日期的版本控制方案?
本 PEP 的早期版本提出了一個用於標準庫的基於日期的版本控制方案。然而,這種方案使得處理週期外發布以修復標準庫版本中的安全問題和其他關鍵錯誤非常困難,因為它需要以下步驟:
- 將釋出版本號更改為當前月份的日期。
- 更新“有什麼新內容?”、NEWS 和文件以引用新發布號。
- 進行新發布。
對於現在提出的順序方案,此類釋出最多隻需要整理一下“有什麼新內容?”文件,然後進行釋出。
為什麼 PEP 384 足夠用?
PEP 384 引入了 CPython 的“穩定 ABI”概念,這是完整 C ABI 的一個有限子集,保證保持穩定。使用穩定 ABI 構建的擴充套件應該能夠支援所有後續的 Python 版本,且二進位制檔案相同。
這將有助於新專案避免將其 C 擴充套件模組與特定 CPython 版本過於緊密地耦合。但是,對於現有模組,遷移到穩定 ABI 可能涉及大量工作(特別是對於定義了大量類的擴充套件模組)。由於可用的開發資源有限,任何花費在此類更改上的時間都可以用於開發為終端使用者提供更直接益處的功能。
與第三方 C 擴充套件的二進位制相容性問題無關,分離版本控制(如上所述)還有其他好處。
為什麼標準庫釋出中沒有二進位制相容的 C ABI 擴充套件?
可以認為,對 CPython C ABI 的新增在標準庫釋出中是合理的。這將使 C 擴充套件作者像其他任何包或模組作者一樣自由地依賴特定的語言版本或標準庫版本。
本 PEP 目前將直譯器版本與語言版本相關聯,因此將主要的直譯器更改(包括 C ABI 新增)限制在語言釋出中。
一個替代的、內部一致的方案是將直譯器版本與標準庫版本相關聯,只有可能影響向後相容性的更改才限制在語言釋出中。
在該方案下,以下更改在標準庫釋出中是可接受的:
- 標準庫更新
- 純 Python 模組中的新功能
- C 擴充套件模組中的新功能(受 PEP 399 相容性要求約束)
- 語言內建函式中的新功能
- 直譯器實現更新
- C ABI 的二進位制相容新增
- 對不影響 AST 或更改位元組碼魔術號的編譯工具鏈的更改
- 核心直譯器 eval 迴圈的更改
- 相應維護版本的錯誤修復
以下更改在語言釋出中是可接受的:
- 新的語言語法
- 標準庫釋出中可接受的任何更新
- 新的棄用警告
- 移除先前已棄用的功能
- AST 的更改
- 需要更改魔術號的位元組碼更改
- C ABI 的二進位制不相容更改(儘管 PEP 384 穩定 ABI 仍須保留)
雖然這種方法可能奏效,但似乎沒有令人信服的理由支援它,而 PEP 中當前描述的方法更簡單易懂。
為什麼不將標準庫完全分離出去?
一個偶爾被討論的概念是使標準庫真正獨立於 CPython 參考實現。
我個人認為,實際進行這樣的更改將花費大量精力卻幾乎沒有回報。沒有標準庫的 CPython 是無用的(構建鏈甚至無法執行,測試套件更不用說)。你也無法建立獨立的純 Python 標準庫,因為太多“標準庫模組”實際上與各自直譯器的內部細節緊密相連(例如,內建函式、weakref、gc、sys、inspect、ast)。
建立一個與先前語言版本相容的獨立 CPython 開發分支,並從此分支釋出標識為單獨標準庫版本號的版本,應該能提供獨立標準庫儲存庫的大部分好處,而痛苦卻小得多。
致謝
感謝 PEP 407 的作者開啟了這次討論,也感謝那些作者和 Larry Hastings 對本 PEP 所提議的初步討論。
參考資料
版權
本文件已置於公共領域。
來源:https://github.com/python/peps/blob/main/peps/pep-0413.rst