Following system colour scheme - Python 增強提案 Selected dark colour scheme - Python 增強提案 Selected light colour scheme - Python 增強提案

Python 增強提案

PEP 605 – CPython 的滾動功能釋出流

作者:
Steve Dower <steve.dower at python.org>, Alyssa Coghlan <ncoghlan at gmail.com>
討論至:
Discourse 帖子
狀態:
已拒絕
型別:
資訊性
建立日期:
2019-09-20
Python 版本:
3.9
釋出歷史:
2019-10-01, 2019-10-06, 2019-10-20

目錄

拒絕通知

此 PEP 已被否決,取而代之的是 PEP 602。潛在的 alpha/beta 交替被認為過於令人困惑,而兩年一次的釋出週期被認為太長。

摘要

長期以來,CPython 的名義功能釋出週期一直是“每 18-24 個月”,近年來,一直穩定在“18 個月”的視窗期內。PEP 607 提供了一些關於該週期選擇所帶來的問題的背景資訊,以及在提出變更建議時需要考慮的風險。

本 PEP 中的提案旨在允許 CPython 的使用者群自行選擇加入兩個不同的但重疊的群體:

  • 使用每 24 個月釋出一次的穩定功能版本(及其相關的維護版本流)的使用者;以及
  • 早期採用替代 CPython 預釋出流程的新滾動版本流的使用者。

作為本提案的一部分,beta 版本的用法指導將從“不得用於生產環境”更改為“僅適用於具有足夠強大的相容性測試和操作監控能力的生產環境”。

同樣,alpha 版本的指導將修改為“旨在用於庫相容性測試和建立 ABI 相容的二進位制產物”,而不是簡單地說“不得用於生產環境”。

PEP 作者認為,透過修改 CPython 的預釋出管理流程(如下文“提案”部分所述)可以實現這些結果。

本 PEP 還建議調整 X.Y.0 版本的釋出頻率,以便在每兩年一次的八月份開始新的版本系列(從 2021 年開始,大約在 Python 3.8.0 釋出兩年後)。

未來發布計劃示例

根據此提案,Python 3.9.0a1 將於 2019 年 12 月釋出,比 2019 年 10 月釋出的 Python 3.8.0 基線功能版本晚兩個月。

假設 CPython 完全 ABI 沒有進一步的中斷性變更,3.9.0b2 版本將在兩個月後,即 2020 年 2 月釋出,一直到 2021 年 4 月的 3.9.0b9。

任何時候,如果引入了 CPython 完全 ABI 的中斷性變更,第一次包含該變更的預釋出版本都將被標記為 alpha 版本。

3.9.0rc1 將於 2021 年 6 月釋出,3.9.0rc2 於 2021 年 7 月釋出,然後完整的版本將作為 3.9.0 於 2021 年 8 月釋出。

週期將於 2021 年 10 月重新開始,釋出 3.10.0a1(在建立 3.9.x 維護分支 4 個月後)。

維護版本釋出的具體時間表將由釋出團隊決定,但假設 3.9.x 的維護版本也將每隔一個月釋出一次(與 3.10.0 beta 版本錯開),那麼總體釋出時間線將如下所示:

  • 2019-12: 3.9.0a1
  • 2020-02: 3.9.0b2
  • … 每隔一個月釋出 beta(或 alpha)版本
  • 2021-04: 3.9.0b9
  • 2021-06: 3.9.0rc1 (功能凍結, ABI 凍結, pyc 格式凍結)
  • 2021-07: 3.9.0rc2
  • 2021-08: 3.9.0
  • 2021-09: 3.9.1, 3.8.x (最終 3.8.x 二進位制維護版本)
  • 2021-10: 3.10.0a1
  • 2021-11: 3.9.2
  • 2021-12: 3.10.0b2
  • … beta(或 alpha)和維護版本繼續交替釋出
  • 2023-04: 3.10.0b10
  • 2023-05: 3.9.11
  • 2023-06: 3.10.0rc1 (功能凍結, ABI 凍結, pyc 格式凍結)
  • 2023-07: 3.10.0rc2, 3.9.12
  • 2023-08: 3.10.0
  • 2023-09: 3.10.1, 3.9.13 (最終 3.9.x 二進位制維護版本)
  • 2023-10: 3.11.0a1
  • 2023-12: 3.11.0b2
  • … 等等

如果我們假設在 3.9.0a5 和 3.9.0a7 版本中引入了兩次額外的 CPython 完全 ABI 中斷性變更的預釋出版本,那麼整體日曆將如下所示:

../_images/pep-0605-example-release-calendar.png

圖 1. 預釋出流程變更對日曆的影響。

在此模型中,始終有兩個或三個活躍的維護分支,這在這一點上保持了現狀。主要區別在於,我們將開始鼓勵釋出者提供滾動預凍結版本的預編譯二進位制檔案,以及為穩定維護分支提供預編譯二進位制檔案。

../_images/pep-0605-overlapping-support-matrix.png

圖 2. 18 個月週期與 24 個月週期的測試矩陣

針對 CPython 完全 ABI 的包釋出者,如果選擇提供滾動預凍結版本的預編譯二進位制檔案,至少需要構建新的 wheel 存檔,從 3.9.0a1 版本釋出開始。後續 alpha 版本(例如示例時間表中的 3.9.0a5 或 3.9.0a7 版本)是否需要釋出更新的二進位制檔案,將取決於他們是否確實受到這些後續 alpha 版本中 ABI 變更的影響。

與現狀一樣,所有希望提供最終版本預編譯二進位制檔案的包釋出者都必須在 ABI 凍結日期後構建新的 wheel 存檔。與現狀不同的是,此日期將透過釋出第一個候選版本(Release Candidate)明確標記,並且將在足夠早的時間發生,以便釋出者有幾個月的時間為最終版本做好準備。

未來發布公告示例

如果此 PEP 被接受,用於將更新的預釋出管理流程傳達給終端使用者的主要渠道將是 Python 3.9 的“新增功能”文件和釋出公告本身。

本節提供可用於這些目的的文字草稿。

建議的“Python 3.9 新增功能”條目

以下子節將新增到 Python 3.9 的“新增功能”文件中,並從每個 Python 3.9 alpha 和 beta 版本公告中連結。

PEP 605:預釋出管理流程變更

PEP 605 所詳述,預釋出管理流程已更新,以生成一系列滾動 beta 版本,這些版本被認為適用於具有足夠強大的整合測試和操作監控能力的生產環境。

在此新的滾動模型下,alpha 和 beta 版本混合在一個稱為“預凍結”的組合階段中。alpha 版本指示 CPython 完全 ABI 的中斷,這可能需要重新編譯擴充套件模組或嵌入式應用程式;beta 版本指示與前一個預釋出版本完全的二進位制相容性。

與之前的版本不同,積極鼓勵釋出 3.9.0 alpha 和 beta 版本的預編譯二進位制檔案,因為在 CPython 完全 ABI 凍結之前構建和載入擴充套件模組時,會設定一個新的預釋出 ABI 標誌(“p”),以確保所有此類預凍結的擴充套件模組構建在凍結後的直譯器構建中將被忽略。

CPython 完全 ABI 將在 3.9.0rc1 中凍結,預釋出標誌將從 ABI 標誌中刪除。預計該版本將在最終 3.9.0 版本釋出前 2 個月釋出(有關確切目標日期,請參閱 PEP 596 中的釋出計劃)。

對於應用程式開發人員來說,遷移到滾動版本流提供了機會,可以在下一個穩定版本釋出之前積極參與標準庫和參考直譯器的增強功能的設計和開發。它還提供了在穩定版本釋出一年或更長時間之前受益於直譯器效能增強的機會。

對於釋出預編譯 wheel 存檔的庫開發人員來說,如果專案已經發布了純 Python wheel(標記為 py3-none-any)或針對穩定 C ABI(標記為 cp38-abi3-<platform> 或早期 CPython 3.x 版本中等效的)的構建,則支援 3.9.x 滾動版本流以及 3.8 穩定版本系列無需採取任何特殊操作。這些相同的 wheel 存檔也將可用於後續的 3.9 穩定版本系列。

對於釋出針對 CPython 完全 ABI 構建的預編譯 wheel 存檔的庫開發人員來說,3.9 穩定版本系列的二進位制檔案需要在 CPython 完全 ABI 凍結後構建(即使用 3.9.0rc1 或更高版本)。

這些庫的開發人員也可以透過構建 3.9.0a1 版本(或後續 beta 版本)並按正常方式釋出結果來選擇支援滾動版本流。

在理想情況下,以此方式構建的二進位制檔案將一直可用到最後一個預凍結版本。但是,如果專案受到預凍結期間 CPython 完全 ABI 的變更影響,則有必要釋出一個維護更新,該更新將受影響的二進位制檔案重新構建,以匹配引入相關介面的 alpha 版本。在這種情況下,應在專案元資料中新增相應的 Python-Requires 條目。例如,如果一個專案受到 3.9.0a5 中引入的 ABI 變更的影響,則應新增的 Python-Requires 條目是:

Python-Requires: >= "3.9.0b6"; python_version == "3.9" and full_python_version != "3.9.0a5"

(此附加元資料確保更新版本不會安裝在提供舊版本 ABI 的早期 3.9 系列預釋出版本上)

與應用程式開發人員一樣,選擇支援滾動版本流的庫開發人員將有機會在穩定版本鎖定多年(或在穩定版本系列中包含臨時 API)*之前*,就新 API 設計提供反饋。

3.9.0a1 版本釋出公告文字示例

這是 Python 3.9 的第一個預覽版本。作為一個 alpha 版本,它旨在用於庫和應用程式相容性測試以及建立 ABI 相容的二進位制產物。不建議在生產環境中使用。

預釋出管理流程變更

CPython 已切換到新的預釋出管理流程,旨在生成一系列滾動 beta 版本,這些版本被認為適用於具有足夠強大的整合測試和操作監控能力的生產環境。有關詳細資訊,請參閱 Python 3.9 的“新增功能”文件(連結到相關部分)。

與 3.8 相比,3.9 系列的主要新功能

Python 3.9 的許多新功能仍在計劃和編寫中。在已實現的主要新功能和變更中:

  • (嗨,各位核心開發者或滾動版本流的使用者,如果您發現某個重要功能在此列表中缺失,請告知 <釋出管理器>。)

Python 3.9 的下一個預釋出版本預計為 3.8.0b2,目前計劃於 2020-02-02 釋出。

3.9.0b2 版本釋出公告文字示例

這是 Python 3.9 的第二個預覽版本。作為一個 beta 版本,它與之前的 3.9.0a1 版本完全二進位制相容。建議僅用於具有足夠強大的整合測試和操作監控能力的生產環境。

(其餘內容與 3.9.0a1 公告相同,但會更新已實現的功能,並且下一個預期版本為 3.9.0b3)

3.9.0a5(中期 alpha 版本)釋出公告文字示例

這是 Python 3.9 的第五個預覽版本。作為一個 alpha 版本,它與之前的 3.9.0b4 版本*不*完全二進位制相容。此版本旨在用於庫和應用程式相容性測試以及建立 ABI 相容的二進位制產物。不建議在生產環境中使用。

3.9.0b4 和 3.9.0a5 之間的 CPython ABI 完全中斷性變更

  • PyObject 結構添加了新欄位 ob_example
  • PyTypeObject 結構移除了臨時欄位 tp_example

支援滾動版本流並需要重新編譯以恢復二進位制相容性的專案,應在其更新版本中新增以下元資料:

Python-Requires: >= "3.9.0b6"; python_version == "3.9" and full_python_version != "3.9.0a5"

(其餘內容與 3.9.0a1 公告相同,但會更新已實現的功能,並且下一個預期版本為 3.9.0b6)

3.9.0rc1 釋出公告文字示例

這是 Python 3.9 的第一個候選版本。作為一個候選版本,此版本現在功能完整,CPython 完全 ABI 已凍結,預釋出標記已從 ABI 相容性標誌中移除。建議僅用於具有足夠強大的整合測試和操作監控能力的生產環境。

準備最終釋出 3.9.0

現在 CPython 完全 ABI 已凍結,針對該 ABI 的庫開發人員應構建併發布 3.9.x 穩定系列的二進位制檔案。

尚未針對滾動版本流進行測試的應用程式開發人員,建議測試他們的應用程式,並報告“移植指南”(連結到相關“新增功能”部分)中未提及的任何相容性迴歸。

計劃於 2021-07-02 釋出第二個候選版本,然後於 2021-08-02 釋出最終的 3.9.0 版本。

與 3.8 相比,3.9 系列的主要新功能

此版本中的一些主要新功能和變更:

  • (嗨,各位核心開發者或滾動版本流的使用者,如果您發現某個重要功能在此列表中缺失,請告知 <釋出管理器>。)

動機

當前的 CPython 預釋出和釋出管理流程是在自動化持續整合和操作監控系統相對不成熟的時代開發的。自那時以來,許多組織已採用部署模型,使其能夠在不增加比其他程式碼更改多多少風險的情況下,整合新的 CPython 功能版本。更新的部署模型,例如輕量級任務專用應用程式容器,也使得在 CI 管道中將應用程式與語言執行時結合起來,然後保持它們在一起,直到整個容器映像隨後被更新的映像替換變得更容易。

鑑於外部環境的變化,PEP 602 提議透過將 CPython 功能版本的釋出頻率從每 18-24 個月增加到每 12 個月,來減少 Python 標準庫和 CPython 參考直譯器的功能交付延遲。

不幸的是,對於許多組織來說,採用新 Python 版本的成本不會隨著版本中變更數量的減少而自動降低,因為主要成本與解決任何已發現的問題無關;主要成本與*搜尋*已發現的問題有關。這種搜尋可能涉及對軟體系統的手動測試、對書面材料的人工審查以及其他活動,這些活動的所需時間與現有系統的規模成比例,而不是與 Python 版本之間的變更數量成比例。

對於第三方庫開發人員來說,成本主要與廣泛使用的*不同 Python 版本數量*有關。這目前往往受到 Python-dev 維護哪些版本以及特定分發者提供哪些最新版本(Debian、Ubuntu LTS 和 RHEL/CentOS 系統 Python 版本尤其流行)的組合影響。除了針對更多 Python 版本進行測試的基本 CI 成本外,更多版本被廣泛使用會使得確定故障報告是專案中的實際錯誤,還是報告使用者環境中的問題變得更加困難。

PEP 602 提議受影響的組織和專案簡單地改為採用每兩個或三個 CPython 版本,而不是嘗試採用每個版本,但這帶來了自己的一系列新問題需要解決,無論是實際的(例如,如果我們期望使用者定期跳過版本,那麼棄用需要覆蓋一個以上版本)還是文化的(例如,隨著更多版本被積極使用,開源庫維護者收到僅發生在他們自己不使用的 Python 版本上的錯誤報告的可能性會大大增加)。

PEP 598 是本 PEP 作者之一最初提出的一個替代方案,旨在透過採用語義版本控制風格的策略來減少功能交付延遲,該策略允許在版本系列中增量交付向後相容的功能,直到該系列達到功能完整狀態。該方案仍然具有一個不利的後果,即對對當前版本管理模型感到滿意的使用者產生可見的變更。

本 PEP 認為,PEP 598PEP 602 存在一個共同的缺陷:它們試圖在單一版本模型中滿足兩個非常不同受眾的需求,這會導致設計要求衝突,以及在這些衝突要求之間做出尷尬的權衡。本 PEP 中的提案旨在透過建立兩個*獨立*的生產就緒版本流來避免這一缺陷,現有版本流基本保持不變,而新版本流則針對最能從減少功能交付延遲中受益的受眾進行定製。

本提案的目標

本 PEP 中的提案基於以下關鍵假設:

  • 絕大多數 Python 使用者並不積極要求新的語言和執行時級別功能,而是僅在他們之前使用的版本不再受支援、他們的 Python 提供商預設切換到提供更新版本、或者足夠多的他們感興趣的變更累積到足以構成升級的令人信服的理由時才進行升級。
  • 對於新版本的許多使用者來說,採用新版本時出現的大部分工作不是源於語言級別的相容性問題,而是源於元件安裝級別的相容性問題(例如,檔名和安裝路徑的變更)。
  • 有一部分 Python 使用者願意在生產環境中執行生產就緒的預釋出版本(類似於 Windows Insider 或 Debian 測試版本),至少用於部分用例。

本 PEP 提案的核心是透過生成一個定期的增量功能版本滾動流來改變 CPython 預釋出流程,並確保這些構建的大多數提供足夠的穩定性,使其適用於適當管理的生產系統。

透過採用這種方法,該提案旨在為幾乎所有 Python 使用者和貢獻者提供改進的結果:

  • 對於新增量功能版本流的使用者,瞄準預釋出階段可以實現比 PEP 602 中提出的年度釋出週期更低的延遲。
  • 對於從事新功能開發的 CPython 核心開發人員來說,預釋出的頻率增加和採用率提高應該能夠改進預釋出反饋週期。
  • 對於穩定版本流的使用者來說,在預釋出期間採用率的提高和反饋週期的改進應該能夠提高其第一個 X.Y.0 版本釋出時的功能成熟度,以及提高生態系統的就緒程度。
  • 對於 Python 庫維護人員來說,滾動釋出的預釋出版本流有望提供比當前預釋出管理流程更多的機會,以便在功能釋出到完整穩定版本之前識別和解決設計問題;以及
  • 對於替代 Python 實現的開發人員來說,滾動預釋出版本流可能為擴充套件模組作者提供額外的動力,將其從 CPython 完全 ABI 遷移到 Python 穩定 ABI,這也將使更多生態系統與不模擬 CPython 完全 C API 的實現相容。

儘管如此,但也承認並非本提案的所有成果都將惠及更廣泛的 Python 生態系統的所有成員:

  • 對於 Python 庫維護人員來說,本 PEP 和 PEP 602 都可能導致使用者壓力,要求支援更快的釋出週期。雖然本 PEP 試圖透過明確標記哪些預釋出版本包含 CPython 完全 C ABI 的潛在中斷性變更來緩解此問題,PEP 602 則試圖透過將完整版本之間的最小時間保持在 12 個月來緩解此問題,但無法完全消除此缺點;
  • 對於第三方擴充套件模組維護人員來說,本 PEP 和 PEP 602 都可能導致使用者壓力,要求開始支援穩定 ABI,以便為新版本提供即時可用的 wheel 存檔。這是否是淨負面影響,將取決於請求如何呈現給他們(如果請求是以一種禮貌的貢獻形式,來自有興趣支援滾動預凍結版本的開發人員,那麼這可能是一個積極的方面);
  • 對於一些依賴於預編譯 wheel 存檔可用性的穩定版本流使用者來說,切換到每 12 個月採用一次新版本可能是一個可接受的增加率,而持續轉向歷史 18-24 個月週期的 24 個月末端將是相對於近期版本使用的 18 個月週期而言不理想的降低率。此提案對這些使用者的淨負面影響將取決於我們是否能夠說服庫維護人員,讓他們覺得值得在 API 和 ABI 凍結之前就支援即將釋出的穩定版本,而不是等到 API 和 ABI 凍結。

提案

本 PEP 中提議的大部分變更僅影響預釋出版本的處理。唯一影響完整版本釋出的變更建議是調整其釋出週期。

穩定版本每兩年釋出一次

由於滾動預凍結版本可供希望使用參考直譯器和標準庫的最新版本使用者使用,本 PEP 提議將 X.Y.0 版本釋出頻率調整為每兩年一次在八月份釋出新穩定版本(從 2021 年開始,大約在 Python 3.8.0 釋出兩年後)。

這一變更可能與擬議的預凍結髮布期處理變更正交,但聯絡在於,如果沒有這些預釋出管理變更,兩年一次完整發布週期的缺點可能會大於優點,而對於 12 個月釋出週期而言,情況則相反(即,有了本 PEP 中提出的預釋出管理變更,12 個月完整發布週期的缺點將大於優點)。

將 alpha 和 beta 階段合併為“預凍結”階段

本 PEP 提議,而不是繼續現狀(即預釋出 alpha 和 beta 階段是獨立的、順序的),而是將它們合併為一個單一的“預凍結”階段,並對版本使用單調遞增的序列號。

“alpha”和“beta”名稱將不再表示不同的階段,而是指示該版本是否包含 CPython 完全 ABI 的中斷性變更。

  • “alpha”版本將是“ABI 中斷”版本,其中基於前一個預釋出版本構建的 CPython 完全 ABI 的擴充套件模組不一定能夠正確載入。
  • “beta”版本將是“二進位制相容”版本,其中基於前一個預釋出版本構建的 CPython 完全 ABI 的擴充套件模組預計能夠正確載入,前提是這些模組符合以下附加標準:
    • 模組不得使用上一個穩定版本系列或開發中的預釋出系列中已刪除或以 ABI 不相容方式更改的任何臨時或私有 C API。
    • 模組不得使用上一個穩定版本系列中已棄用並在此 beta 版本中刪除的任何 C API。

預凍結階段的持續時間和節奏

預凍結版本將始終穩定地每兩個月釋出一次,而不是在準備新的 X.Y.0 版本期間每月釋出一次,持續幾個月。

唯一例外情況是在即將釋出的 X.Y.0 版本為期兩個月的候選釋出(Release Candidate)期間(有關更多詳細資訊,請參閱下文的候選釋出部分)。這意味著將跳過兩個計劃中的釋出(一個對應第一個候選釋出日期,一個對應最終釋出日期)。

預凍結階段通常預計在 preceding 穩定 X.Y.0 版本釋出後 2 個月開始。

任何新版本系列的第一個預凍結版本始終是 X.Y.0a1(因為沒有具有相同 ABI 版本標記的前版本可用於判斷二進位制相容性)。

預凍結版本將在其 C ABI 相容性標記中新增一個額外的標誌,以避免與最終穩定版本產生二進位制相容性問題。

beta 版本釋出策略

本 PEP 提議 beta 版本的策略如下:

  • 與當前 beta 版本一樣,預計在準備和釋出 beta 版本之前,穩定的 BuildBot 佇列將保持綠色。
  • 與當前 beta 版本一樣,釋出管理器預計將在準備和釋出 beta 版本之前審查開啟的釋出阻塞問題。
  • 與當前 beta 版本一樣,預計 abi3 穩定 C ABI 的任何新增都將成為該 ABI 的永久組成部分,除非並直到該穩定 ABI 版本完全退役(注意:目前沒有計劃增加穩定 ABI 版本)。
  • 與當前 beta 版本不同,本 PEP 下的 beta 版本*不*會被視為下一個 X.Y.0 版本的完整功能。
  • 與當前 beta 版本不同,所有自上次 CPython 功能版本以來新增的 API(穩定 C ABI 的新增除外)都將被視為臨時性的。
  • 與當前 beta 版本不同,本 PEP 下的 beta 版本將從主開發分支準備和釋出。
  • 與當前 alpha 或 beta 版本不同,本 PEP 下的 beta 版本必須與系列中緊接的前一個預釋出版本完全 ABI 相容(排除對臨時 API 的更改或刪除在前一個版本系列中已棄用的 API)。

alpha 版本釋出策略

本 PEP 提議 alpha 版本的策略如下:

  • 與當前 alpha 版本一樣,預計在準備和釋出 alpha 版本之前,穩定的 BuildBot 佇列將保持綠色。
  • 與當前 alpha 版本一樣,釋出管理器預計將在準備和釋出 beta 版本之前審查開啟的釋出阻塞問題。
  • 與當前 alpha 版本不同,即使是 alpha 版本,釋出管理器也應目標達到與當前 beta 版本相似的穩定性級別。

根據本 PEP,當無法釋出滿足 beta 版本標準的版本時,並且允許額外的時間也無法解決問題時,就會發布 alpha 版本。

預計 CPython 完全 API 的中斷性變更(例如,在公共結構定義中新增或刪除欄位)將是釋出額外的 alpha 版本(除了定義 X.Y.0a1 版本的初始相容性標籤之外)的最可能原因,但任何特定版本的決定權在於釋出管理器。

候選釋出(Release Candidate)策略、階段持續時間和節奏

鑑於 alpha 和 beta 釋出階段的擬議變更,候選釋出階段將看到以下相關調整:

  • 功能凍結、ABI 凍結、pyc 檔案格式凍結和維護分支建立都將與 X.Y.0rc1 的建立同時發生(目前這些發生在 X.Y.0b1、最後一個 beta 版本和 X.Y.0rc1 之間)。
  • X.Y.0 版本候選釋出期將從 3 周延長至 2 個月。
  • 通常會每月釋出兩個候選版本,但釋出管理器可以自行決定釋出額外的候選版本。
  • 最終的 X.Y.0 版本將在最後一個候選版本釋出後 1 到 4 周內釋出(取決於第二個之後是否需要額外的候選版本)。
  • 如果最終的 X.Y.0 版本延遲到八月目標日期之後,後續版本系列不受影響,仍將安排在八月(現在比原計劃的兩年少一點)。

除了為終端使用者提供更多時間反饋候選版本外,這一調整後的策略還為 Python 專案的維護者提供了更多時間來構建和釋出新穩定版本的預編譯 wheel 存檔,從而顯著改善 X.Y.0 版本的初始使用者體驗。

CPython 穩定 ABI 管理變更

CPython 穩定 ABI [5] 承諾,使用特定 CPython 版本構建的二進位制擴充套件模組將在支援相同穩定 ABI 版本的未來 CPython 版本中繼續工作(該版本當前為 abi3)。

根據提議的滾動預凍結版本模型,此承諾也將適用於 beta 版本:一旦即將釋出的 Python 版本的 abi3 穩定 ABI 的有意新增在 beta 版本中釋出,那麼只要 abi3 穩定 ABI 仍然受支援,它就不會從未來的版本中移除。

將提供兩個主要機制來獲取對穩定 ABI 新增的社群反饋:

  • 首選機制是將新 API 新增到 CPython 完全 API 中,並在至少一個釋出的 beta 版本中包含該 API 並獲得相關使用者反饋後,再將其提升到穩定 ABI。
  • 對於由於某種原因(例如,某些 API 新增在 CPython 完全 API 可用時沒有用處)無法採用該方法的 API,開發人員可以請求釋出管理器將下一個版本標記為 alpha 版本(即使 CPython 完全 ABI 沒有中斷),並嘗試透過這種方式獲得進一步反饋。

為了提高可讀性和可用性,本 PEP 還提議為每個主要的穩定 ABI 版本引入別名。

#define Py_LIMITED_API_3_3 0x03030000
#define Py_LIMITED_API_3_4 0x03040000
#define Py_LIMITED_API_3_5 0x03050000
#define Py_LIMITED_API_3_6 0x03060000
#define Py_LIMITED_API_3_7 0x03070000
#define Py_LIMITED_API_3_8 0x03080000
#define Py_LIMITED_API_3_9 0x03090000
// etc...

這些將用於擴充套件模組程式碼中設定目標 ABI 版本,

#define Py_LIMITED_API Py_LIMITED_API_3_8

以及用於 CPython 直譯器實現中檢查哪些符號應可用。

#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= Py_LIMITED_API_3_9
// A Python 3.9+ addition to the stable ABI would appear here
#endif

滾動預凍結版本的文件和穩定 C ABI 將明確指出,使用後期預凍結版本中穩定 ABI 構建的擴充套件模組在早期預凍結版本上可能無法正確載入。

alpha 版本和穩定 C ABI 的文件將明確指出,即使是使用 alpha 版本中穩定 ABI 構建的擴充套件模組,如果連續釋出了兩個 alpha 版本,在下一個版本上也可能無法正確載入(這種情況理想情況下應該很少見)。

CPython 完全 ABI 管理變更

本 PEP 提議對 CPython 完全 ABI 的管理進行兩項變更。

標記 ABI 中斷性變更的提交和 NEWS 檔案約定

本 PEP 的提案要求釋出管理器能夠根據預凍結版本是否包含 ABI 中斷性變更,將其適當地標記為 alpha 或 beta 版本。

為協助此過程,核心開發人員將被要求在所有 NEWS 檔案片段的開頭包含“(CPython ABI break)”標記,用於介紹引入 CPython 完全 C ABI 中斷性變更的內容。

包含“CPython”標記是為了明確這些註釋與完全 CPython ABI 相關,而不是與穩定 ABI 相關。

對於提交訊息,較短的標記“(ABI break)”將放置在提交的摘要行開頭。

預合併機器人將被更新,以確保如果 ABI 中斷標記出現在這兩個位置中的一個,則也出現在另一個位置。

如果標記無意中從初始提交訊息和 NEWS 條目中遺漏,那麼在新增標記到 NEWS 條目的後續提交中應包含提交訊息標記。

除了對釋出管理器有用外,這些標記對於調查在受影響版本上測試時出現的意外分段錯誤(segfault)的開發人員也應該有用。

明確標記基於預凍結 ABI 的構建

CPython 完全 ABI 長期以來一直遵循一項政策,即二進位制相容性僅在 ABI 被宣佈凍結後在一個版本系列內適用,而不同版本系列之間只適用原始碼相容性。

此政策意味著,在 ABI 凍結日期之前使用 CPython 預釋出版本構建的擴充套件模組,在最終版本上可能無法正確載入。

這是因為擴充套件模組可能依賴於在後續 alpha 或 beta 版本中已更改或刪除的臨時或先前已棄用的介面,或者它可能是由於用於擴充套件模組的公共結構因新增新欄位而改變了大小。

歷史上,alpha 和 beta 版本的採用率足夠低,以至於這在實踐中並沒有真正成為一個問題。然而,本 PEP 提議積極鼓勵 beta 版本在生產環境中的廣泛使用,因此希望確保這些版本的使用者不會無意中釋出二進位制擴充套件模組,從而導致執行候選版本和最終版本的使用者出現分段錯誤。

為此,本 PEP 提議在非 Windows 系統上修改擴充套件模組 SOABI 標記,以包含一個新的“p”標誌用於 CPython 預釋出版本,並且只有在特定 X.Y.0 版本的 ABI 已在進入候選釋出階段時凍結後,才恢復為省略該標誌。

透過此更改,3.9.0 的 alpha 和 beta 版本將獲得 SOABI 標籤 cpython-39p,而所有候選版本和最終構建(無論是 3.9.0 還是後續的 3.9.x 版本)將獲得未加標記的 SOABI 標籤 cpython-39

除錯構建仍將在標籤末尾新增“d”,為預釋出版本的除錯構建提供 cpython-39pd

在 Windows 系統上,預釋出構建中標記的 pyd 檔案的字尾將在版本號之後立即包含“p”作為預釋出標記,提供類似“cp39p-win_amd64”的標記。

此變更的擬議參考實現可在 [4] 找到(注意:撰寫本文時,該實現尚未在 Windows 上進行測試)。

更新受完全 ABI 變更影響的專案所需的 Python 版本

當一個專案首次選擇為滾動預凍結版本系列提供預編譯二進位制 wheel 時,它們不需要做任何特殊的事情:它們會將滾動版本系列新增到其構建和測試矩陣中,併發布標記為與該版本系列相容的二進位制存檔,就像它們在該版本系列的 CPython 完全 ABI 凍結後提供預編譯二進位制 wheel 一樣。

但是,如果專案受到滾動版本流中 CPython ABI 相容性中斷的影響,那麼它們需要釋出一個版本更新,該更新包括新的二進位制構建和新的環境約束 Python-Requires 標記。

例如,如果一個支援滾動版本流的專案受到了 3.9.0a5 版本中 CPython ABI 相容性中斷的影響,那麼它們將在釋出更新二進位制版本的版本中新增以下元資料條目:

Python-Requires: >= "3.9.0b6"; python_version == "3.9" and full_python_version != "3.9.0a5"

這會做什麼?它在釋出的包中添加了一個額外的相容性約束,因此 3.9.0 beta 版本(早於 3.9.0b6)將不會將更新的包視為安裝候選,並且唯一會考慮該包的 alpha 版本是 3.9.0a5 本身。

注意事項和限制

實際釋出日期最多可能提前或推遲一個月,由釋出管理器根據釋出團隊的可用性以及其他事件(例如 PyCon US 或年度核心開發衝刺)的時間來決定。但是,由於該提案的目標之一是提供一致的釋出週期,因此調整應該是罕見的。

在一個版本系列中,維護版本的確切釋出頻率仍然由釋出管理器和二進位制釋出團隊決定;本 PEP 僅提議了預釋出版本和 X.Y.0 版本的預期釋出週期。

但是,為了示例時間線的目的,PEP 假設維護版本每隔一個月釋出一次,允許它們與滾動預凍結版本交替釋出。

釋出管理器和指導委員會還將保留修改本 PEP 中各項提案細節的權力。可能的修改包括(但不限於):

  • 更改維護分支的建立時間。如果一個需要新 alpha 版本的主要變更在預釋出流程的後期才合併,釋出管理器可能會選擇從該主要變更之前的點分叉。例如,如果下一個計劃釋出的版本是最終 beta 版本或第一個候選版本,這樣做可能是合理的。
  • 將宣告 alpha 版本的標準可能擴充套件到包括所有需要“移植”條目到“新增功能”文件中的變更。
  • 釋出管理器可以預先宣佈一些日期為 alpha 版本,並要求核心開發人員相應地安排他們的風險較高的變更,而不是按需宣告 alpha 版本。

PEP 中具體提案的目的是提供一個清晰的說明性示例供審閱者考慮,而不是限制我們根據該流程的實際經驗來調整具體細節的能力。

設計討論

為何選擇滾動預凍結版本而不是簡單地進行更頻繁的 X.Y.0 版本釋出?

對於 Python 的大部分使用者來說,新 CPython 功能版本*的可用性*並不是他們採用這些新版本的限制因素(這一影響在 PyPI 下載元資料等指標中可見)。

因此,任何基於加速完整功能釋出頻率的提案都需要在滿足每個版本釋出時都進行採納的使用者需求,以及那些現在將處於採用每 2 個、3 個或 4 個版本,而不是在其生命週期內的某個點幾乎能夠遷移到每個版本的情況的使用者需求之間取得平衡。

本提案旨在從不同角度解決問題,即定義一個*新的*生產就緒版本流,該版本流更專門地針對那些能夠以 CPython 核心團隊準備生成的速度消耗新版本的操作環境。

是否必須保留“alpha”和“beta”命名方案?

使用擬議的滾動版本的前“a”和“b”初始字母,是 CPython 版本號釋出方式的一些實際方面所強制的設​​計約束。

具體來說,alpha 版本、beta 版本和候選版本在某些地方使用字串“a”、“b”和“c”表示,而在其他地方則使用十六進位制數字 0xA0xB0xC 表示。我們希望保留這一點,同時確保任何 Python-Requires 約束都是針對 beta 版本而不是 alpha 版本(因為後者在連續釋出兩個 alpha 版本時可能無法強制執行 abi3 穩定性要求)。

然而,沒有什麼能強迫我們說“a”代表“alpha”或“b”代表“beta”。

這意味著,如果我們想增加那些僅因“beta”標籤而猶豫的人的採用率,那麼強調“*A*BI 中斷”和“*B*inary 相容”的名稱而不是“alpha”和“beta”的名稱可能會有意義,例如:

  • 3.9.0a1:ABI 中斷的預凍結版本
  • 3.9.0b2:二進位制相容的預凍結版本
  • 3.9.0rc1:候選版本
  • 3.9.0:最終版本

本 PEP 的當前迭代並未走那麼遠,因為將滾動預凍結版本的初始採用限制在那些對“beta”標籤感到滿意的人身上可能是一件好事,因為這些版本的早期採用者將遇到更廣泛的 Python 生態系統中出現的任何意外後果,我們需要他們願意積極參與解決這些問題。

因此,假設結果足夠積極,以至於我們認為這種方法值得繼續,那麼未來可以考慮放棄“beta”命名。

為何選擇滾動預凍結版本而不是在穩定和不穩定版本系列之間交替?

使用滾動版本而不是 beta 週期,另一種選擇是傳統穩定版本(用於 3.8.x、3.10.x 等)和使用新滾動版本週期的版本系列(用於 3.9.x、3.11.x 等)之間交替。

這個想法存在與 PEP 598PEP 602 相同的核心問題:它對對現狀感到滿意的使用者施加了變更,而沒有提供任何明確的補償性好處。

它還受到反對 PEP 598 的主要擔憂之一的影響:至少一些核心開發人員和終端使用者強烈認為,不應為版本號的*值*分配任何特定的語義。這些社群成員反而認為,所有語義意義都應與版本號中改變的*位置*相關聯。

相比之下,滾動預凍結版本提案旨在透過確保擬議的政策變更都圍繞特定版本是 alpha 版本、beta 版本、候選版本還是最終版本來解決這一擔憂。

為何不為滾動釋出流使用日曆版本控制?

Steve Dower 的初始提案撰寫 [1] 建議對滾動版本流使用日曆版本控制(因此,Python 3.8.0 之後的第一個滾動預釋出版本將是 Python 2019.12 而不是 3.9.0b1)。

Paul Moore 指出了 [2] 該提案的兩個主要實際問題:

  • 使用者將無法清楚地瞭解基於日曆的版本與傳統編號版本之間的關係。
  • 它破壞了 Python-Requires 元資料在打包工具中的處理,並且沒有明確的方法可以可靠地修復它(因為所有日曆版本都將比任何標準版本看起來都新)。

本 PEP 旨在透過使用已建立的 beta 版本號來解決這兩個問題,用於滾動版本。

例如,考慮以下問題:“Python 2021.12 是否包含 Python 3.9.0 中釋出的所有新功能?”。使用滾動版本的日曆版本控制,無法回答此問題,除非查閱釋出日曆以瞭解 3.9.0rc1 何時從滾動版本流中分叉。

相比之下,滾動預凍結版本的等效問題很容易回答:“Python 3.10.0b2 是否包含 Python 3.9.0 中釋出的所有新功能?”。僅從問題的措辭就可以清楚地得出答案:“是的,除非它們是已刪除的臨時功能”。

beta 版本編號方法也避免了日曆版本控制概念提出的其他問題,例如 sys.version_infoPY_VERSION_HEXsite-packages 目錄命名以及安裝的 Python 二進位制和擴充套件模組命名將如何工作。

滾動預凍結版本的使用者如何檢測 API 變更?

在新增新功能時,將大力鼓勵核心開發人員透過不依賴於 sys.version_info 或執行時程式碼物件內省的機制來支援功能檢測和優雅回退到替代方法。

在大多數情況下,對受影響模組進行簡單的 hasattr 檢查即可達到此目的,但當不滿足時,將作為功能新增的一部分考慮替代方法。此領域的先例包括 pickle.HIGHEST_PROTOCOL 屬性、hashlib.algorithms_available 集合以及 os 模組已為平臺特定功能檢測提供的各種 os.supports_* 集合。

還可以新增需要在使用滾動預凍結版本中首次包含時透過 __future__ 匯入顯式啟用的功能,即使該功能標誌隨後在 X.Y.0 版本候選釋出首次出現之前預設啟用。

這些方法的理由是,顯式檢測/啟用(例如 from __future__ 匯入如果功能標誌不再存在,則會在編譯時中斷)將使滾動預凍結版本流的使用者能夠輕鬆地注意到我們何時刪除或更改臨時功能,或者安全地回退到先前的功能。

直譯器豐富的屬性查詢機制意味著我們還可以選擇為臨時或已棄用的匯入和屬性新增警告,而我們無法透過檢查 sys.version_info 的值來處理這些情況。

為何要新增新的預凍結 ABI 標誌來強制在 X.Y.0rc1 之後重新編譯?

CPython 核心開發團隊目前積極*不鼓勵*在 ABI 凍結日期之前建立 X.Y 系列的公共預編譯二進位制檔案。

我們這樣做的原因是避免在穩定 X.Y.0 版本上出現痛苦的除錯會話,這些會話追溯到“哦,我們的依賴項‘superfast-binary-operation’受到了 X.Y.0a3 中 CPython ABI 中斷的影響,但該專案自那以後沒有釋出新版本”。

透過在 CPython X.Y 版本系列上啟用提議的預凍結 ABI 標誌,此釋出採用過程的這一方面基本保持不變:新的 CPython X.Y 版本系列達到 ABI 凍結 -> 包維護者為該版本系列釋出新的二進位制擴充套件模組 -> 終端使用者僅因實際錯誤而遇到分段錯誤,而不是僅僅因為構建與不相容的 ABI 相關。

新的預凍結 ABI 標誌的主要目標是改善滾動預凍結版本本身的體驗,允許為這些版本釋出預編譯二進位制存檔,而不會冒著目前導致我們積極不鼓勵在 ABI 凍結之前釋出二進位制產物的風險。

在理想情況下,包維護者只需在 X.Y.0a1 版本釋出一個預凍結二進位制構建,然後在 X.Y.0rc1 之後釋出一個凍結後構建。在此期間僅*需要*重建的情況僅限於專案實際受到中間 alpha 版本中 ABI 中斷的影響。

例如,考慮一種情況,我們最終有三個版本包含 ABI 中斷:X.Y.0a1、X.Y.0a5、X.Y.0a7。然後,X.Y.0a7 的 ABI 將貫穿所有後續的 beta 版本並進入 X.Y.0rc1。(這是圖 1 中說明的情況)

強迫每個人在滾動版本流中的每次 alpha 版本釋出時都重建整個世界,幾乎肯定會導致釋出者認為支援滾動版本弊大於利,因此我們希望允許將使用 X.Y.0a1 構建的模組載入到 X.Y.0a7 上,因為它們*可能*是相容的(很少有專案會使用 CPython 釋出的所有 C API,並且大多數 ABI 中斷只會影響單個特定 API)。

然而,一旦我們釋出了 X.Y.0rc1,我們就希望確保那些使用 X.Y.0a1 和 X.Y.0a4 構建的二進位制檔案完全從終端使用者體驗中移除。雖然能夠保留 X.Y.0a7 及後續 beta 版本(因為事實證明那些實際上是針對凍結後 ABI 構建的,即使當時我們不知道)的構建是好的,但丟失它們並不會比現狀*更糟*。

這意味著預凍結標誌是“最簡單的可能工作的”來解決這個問題——它只是一個新的 ABI 標誌,我們已經擁有處理 ABI 標誌的工具(無論是在直譯器中還是在包釋出和安裝工具中)。

由於 ABI 標誌相對於預釋出版本發生了變化,專案甚至不需要釋出新版本:它們可以將新的 wheel 存檔上傳到其現有版本中,就像今天一樣。

雖然一個更巧妙的方案,能夠追溯接受所有在最後一個 alpha 版本或後續 beta 版本上構建的內容,但對於採用本 PEP 來說,它並不被認為*必需*,因為即使我們最初採用簡單的預釋出 ABI 標誌,未來仍然可能設計出更復雜的方案。

為何允許在 X.Y.0a1 之後釋出其他 alpha 版本?

在理想情況下,CPython 完全 ABI 的所有中斷性變更都將在 X.Y.0a1 版本中與檔案系統佈局變更一起出現,並且該版本系列的 ABI 將從此保持穩定。

然而,最近的歷史表明,我們無法真正做出這一承諾並堅持下去,因此 PEP 假設 ABI 變更將在預凍結期間逐步進行,並且在準備 X.Y.0rc1 時建立 X.Y.z 維護分支時才會進行完全鎖定。

對 CPython 核心開發的影響

CPython 核心開發的主要變化是需要使主分支更穩定地為釋出做好準備。

雖然主要要求是保持穩定的 BuildBot 佇列綠色,但也會鼓勵保持開發版本的文件最新,以造福滾動預凍結版本的使用者。這將包括為已實現的功能提供“新增功能”條目的草稿,儘管初始版本可能相對稀疏,然後根據 beta 版本使用者的反饋進行擴充套件。

對於從事 CPython C API 開發的核心開發人員,還將需要一致地在其 NEWS 檔案片段中標記 ABI 中斷性變更。

關於穩定 ABI 的具體主題,大多數 API 設計都可以透過一個過程,首先將其作為 CPython 完全 API 的臨時部分引入(允許在預凍結版本之間進行更改),並在開發人員確信介面確實穩定後,再將其提升到穩定 ABI。

只有在 API 在穩定 ABI 之外沒有用處等罕見情況下,才可能釋出包含臨時穩定 ABI 新增的 alpha 版本,而不是在 CPython 臨時 API 中迭代設計。

對 Python 庫開發的影響

如果本 PEP 成功實現了其目標,那麼對於庫作者來說,支援滾動預凍結版本流的痛苦程度將不會比支援穩定版本大多少。

對於純 Python 包的釋出者來說,這將是釋出標記為“py3”的 wheel 存檔,並且可能將滾動預凍結版本流新增到他們的測試矩陣中,如果該選項可用的話。

對於二進位制擴充套件模組的釋出者來說,首選選項是(如果可行)瞄準穩定 C ABI,從而獲得與純 Python 包類似的體驗,即一個預編譯的 wheel 存檔可以覆蓋多個 Python 版本,包括滾動預凍結版本流。

此選項並非對所有庫都可行,並且對於那些作者來說,期望他們透過構建和釋出一個額外的 wheel 存檔來支援滾動版本,該存檔是在初始 X.Y.0a1 版本上構建的。然後,在 X.Y.0rc1 或更高版本上的後續構建與僅支援最終穩定版本所需的構建相同。

此後,只有在該特定庫受到這兩個點之間發生的任何其他 alpha 版本中的 ABI 中斷直接影響的情況下,才需要額外的 wheel 構建。

提供一個滾動預凍結版本流也可能使更多的 CI 提供商能夠提供“CPython beta 版本”測試選項。目前,只有那些願意並有能力投入必要的時間和精力來建立、測試和釋出 CPython 主分支的構建的 CI 提供商才能使用此功能(例如,[6])。

對擬議的科學 Python 生態系統支援期的影響

基於 SciPy 2019 的討論,已經起草了 NEP(NumPy 增強提案)29 [3],以在科學 Python 生態系統中提出一個通用的約定,用於停止支援舊的 Python 版本。

雖然該策略的確切表述仍在討論中,但草案提案(截至 2019 年 10 月 20 日)建議專案支援過去 42 個月內釋出的任何 Python 功能版本,最低要求是支援最新的 2 個 Python 功能版本。

對於 18 個月的功能釋出週期,這意味著始終至少支援最近的兩個功能版本,然後在 X.(Y+2).0 釋出後大約 6 個月內停止支援所有 X.Y.Z 版本。這意味著大約每兩年會有 6 個月的視窗期,在此期間支援三個最近的功能版本。

對於 12 個月的功能釋出週期,這意味著始終至少支援最近的三個功能版本,然後在 X.(Y+3).0 釋出後大約 6 個月內停止支援所有 X.Y.Z 版本。這意味著每年的前半部分將支援四個最近的功能版本,後半部分有望用於準備當年的功能版本。

對於 24 個月的功能釋出週期,第二個條款優先於第一個條款,並且為了持續支援兩個最近的 CPython 功能版本,建議的 Python 版本支援期從最初的 X.Y.0 版本釋出起延長至 48 個月。對於也支援滾動版本流的專案,支援的功能版本數量將增加到三個。

核心開發衝刺(sprint)的釋出週期對齊

透過本 PEP 的提案,預計核心開發衝刺的重點將根據兩年週期中的當前位置略有轉移。

在釋出年份,PyCon US 的時間適合新貢獻者在第一個候選版本釋出之前處理錯誤修復和小型功能,而語言峰會和核心開發人員的討論可以專注於下一個版本系列的計劃。

釋出年份的預 alpha 核心開發衝刺將提供一個機會,將前一個版本收到的反饋納入其中,無論是作為下一個維護版本(用於錯誤修復和對臨時 API 的反饋),還是作為下一個版本系列(用於對穩定 API 反饋)的第一個 alpha 版本。

這些初始 alpha 版本也將是 CPython 完全 ABI 的 ABI 中斷性變更的首選目標(儘管如本 PEP 中所述,在此釋出週期的後期仍然允許進行變更,但將其合併到 X.Y.0a1 版本意味著它們不會給預編譯二進位制包的釋出者帶來額外的工作)。

下一個釋出週期的指導委員會選舉也很可能在預 alpha 開發衝刺的同時進行。

在非釋出年份,這兩個活動的重點將僅限於即將到來的維護和預凍結版本。這些不太緊張的年份有望提供機會來處理各種流程變更和基礎設施升級,而不會影響候選釋出準備過程。

主流 Linux 發行版的釋出週期對齊

一些滾動釋出的 Linux 發行版(例如 Arch、Gentoo)可能能夠使用本 PEP 提議的新滾動預凍結版本,但預計大多數發行版將繼續使用已釋出的版本。

本 PEP 中為最終釋出提議的具體日期選擇是為了與 Ubuntu 和 Fedora Linux 發行版每年十月釋出的日期凍結計劃保持一致。

對於 Fedora 和 Ubuntu 來說,這意味著候選釋出階段與發行版釋出的開發週期一致,這是他們測試新版本並提供有關潛在迴歸和相容性問題的反饋的理想時間。

對於 Ubuntu 來說,這意味著他們的四月 LTS 版本將受益於使用新系統 Python 版本的完整短期釋出週期,同時該 CPython 版本在其釋出到下一個 Ubuntu LTS 版本之前的大部分時間都可以進行上游錯誤修復。

與本 PEP 中的具體提案可能一直不佳的 Linux 釋出週期對齊是 Debian,因為它自 2005 年以來一直在奇數年份的上半年釋出(大致偏移 Ubuntu LTS 版本 12 個月)。

根據 PEP 602 中的年度釋出提案,Debian 和 Ubuntu 都將始終獲得大約 6 個月大的系統 Python 版本,但彼此之間也會選擇不同的 Python 版本。

對於兩年週期,並且 CPython 版本在下半年釋出,它們很可能選擇相同的版本,但其中一個將選擇一個比最新的 beta 版本晚 18 個多月的 CPython 版本,直到 Linux 發行版釋出。

如果這種情況發生,並且被認為是不理想的(但又不至於讓*Debian*選擇調整其釋出時間),那麼 PEP 598 中的“增量功能釋出”提案的額外複雜性可能會變得有價值。

(將 CPython 版本移動到與 Debian 和 Ubuntu LTS 釋出相同的半年期可能有助於緩解問題,但也會產生新問題,即 CPython 釋出時間表的延遲可能會直接影響 Linux 發行版的釋出時間表,或者導致發行版釋出一個比最新的 beta 版本晚 18 個多月的 Python 版本)。

對簡單部署環境的影響

就本 PEP 而言,“簡單”部署環境是指任何易於確保所有目標環境同時更新到新 Python 版本(或至少在更高層應用程式版本釋出之前)的用例,並且任何預釋出測試僅需要針對單個 Python 微版本。

最簡單的此類情況是指令碼的個人使用,此時測試和目標環境完全相同。

同樣簡單的環境是容器化 Web 服務,其中 CI 管道中使用的 Python 容器與部署中使用的相同,以及任何捆綁自己 Python 執行時而不是依賴於目標系統上已有的 Python 部署的應用程式。

對於這些用例,有一種直接的機制可以最大限度地減少此 PEP 的影響:繼續使用穩定版,並忽略滾動式預凍結版。

要在這些環境中實際採用滾動式預凍結版,主要挑戰將是如何處理擴充套件模組段錯誤的可能性,當下一版預凍結版是 alpha 版而不是 beta 版時,這表明 CPython ABI 可能發生了不相容的更改。

如果所有使用的擴充套件模組都以穩定 ABI 為目標,那麼就沒有問題,一切都會像穩定版一樣順利執行。

或者,“重新構建和重新快取所有擴充套件模組”可能成為更新到 alpha 版時進行的標準活動。

最後,直到出現問題為止都不去擔心它,然後像處理新 alpha 版或 beta 版中發現的任何其他庫相容性問題一樣來處理它,也是合理的。

除了擴充套件模組 ABI 相容性之外,使用滾動式預凍結版時產生的其他主要額外複雜性將是獨立版本化功能(如 pickle 和 SQLite)的“回滾”相容性,其中使用 beta 流中的新功能或臨時功能可能會建立穩定版無法讀取的檔案。使用這些型別的功能並還需要能夠可靠地回滾到以前的穩定 CPython 版本,像今天一樣,建議避免採用預釋出版本。

對複雜部署環境的影響

就本 PEP 而言,“複雜”部署環境是指不符合上述“簡單部署”標準的用例。它們可能涉及多個不同的 Python 版本,使用個性化的 Python 構建,或者需要“看門人”在部署前批准新版本的使用。

例如,將 Python 作為標準作業系統環境的一部分安裝在其使用者機器上的組織屬於此類,提供標準構建環境的組織也是如此。像 conda-forge 或 WinPython 這樣提供一致構建和驗證的軟體包集合的發行版也受到類似方式的影響。

這些組織傾向於偏愛高穩定性(例如,所有那些愉快地使用穩定 Linux 發行版(如 Debian、RHEL/CentOS 或 Ubuntu LTS)中的系統 Python 作為其首選 Python 環境的人)或快速週轉(例如,那些經常為最新 CPython 預釋出版做出貢獻的人)。

在某些情況下,同一組織中可能為了不同的目的而存在這兩種使用模式,例如

  • 為任務關鍵型系統使用穩定的 Python 環境,但允許資料科學家使用可用的最新版本進行 ad hoc 資料分析
  • 硬體製造商將穩定的 Python 版本作為其生產韌體的一部分進行部署,但在其自動化整合測試的開發和執行中使用可用的最新版本

在任何釋出模型下,Python 的每個新發布都會為這些組織帶來工作。這些工作可能涉及對 Python 本身的法律、安全或技術審查,評估和驗證有影響力的更改,重新應用補丁,重新編譯和測試第三方依賴項,然後才能進行部署。

能夠快速獲得更新的組織應該能夠利用更頻繁的 beta 版本。雖然每次更新仍然需要與今天相似的調查工作,但每次釋出的工​​作量應該會減少,因為每次釋出將比當前模型下的釋出更相似。擬議的“每 2 個月釋出一次”模型的優點之一是,組織可以選擇自己的採用週期,從採用每個 beta 版本,到每季度採用一個,或者每 6 個月採用一個,或者每年採用一個。在此之外,繼續使用穩定版可能會更有意義。

對於評估更嚴格或偏好穩定的組織來說,更長的穩定版釋出週期將減少更新所需的年度工作量,更長的釋出候選期將允許在 X.Y.0 釋出之前進行更長的內部測試時間,並且在 beta 期間被其他人更廣泛地使用將為初始版本提供更大的信心。同時,組織可以放心地在維護版本之間進行更長時間的升級,而不必擔心破壞性更改。

致謝

感謝 Łukasz Langa 建立 PEP 602 並促使討論 CPython 釋出節奏的可能改進,感謝 Kyle Stanley 和 h-vetinari 對本 PEP 初稿的建設性反饋。

參考資料


來源:https://github.com/python/peps/blob/main/peps/pep-0605.rst

最後修改:2025-02-01 08:59:27 GMT