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

Python 增強提案 (Python Enhancement Proposals)

PEP 592 – 為 Simple API 新增「撤銷 (Yank)」支援

作者:
Donald Stufft <donald at stufft.io>
BDFL-Delegate:
Paul Moore <p.f.moore at gmail.com>
討論於:
Discourse 討論串
狀態:
最終 (Final)
類型:
標準軌跡 (Standards Track)
主題:
套件封裝 (Packaging)
建立日期:
2019年5月7日
決議:
Discourse 訊息

目錄

摘要

本 PEP 提議在簡單儲存庫 (simple repository) 中新增將特定檔案下載標記為「已撤銷 (yanked)」的功能。撤銷檔案允許作者有效地刪除檔案,且不會破壞那些已鎖定特定版本使用者的環境。

同時,本 PEP 也將簡單儲存庫 API 的權威來源變更為 Simple Repository API 參考文件。

動機

每當專案發現 PyPI 上的特定版本可能損壞時,他們通常會希望防止後續使用者無意間使用該版本。然而,直接從儲存庫刪除檔案這個顯而易見的解決方案,會破壞那些遵循最佳實踐並鎖定專案特定版本的使用者環境。

這使專案陷入兩難:新專案可能會下載到這個已知的損壞版本,但若要阻止此行為,就會破壞已經在使用該版本的專案。

藉由允許「撤銷」檔案,但同時讓明確要求該檔案的使用者仍能取得,專案可以在緩解嚴重損壞的同時,讓那些已經繞過問題或未遇到潛在問題的專案繼續運作。

這類情況的主要場景之一,是放棄對特定 Python 版本的支援時。python-requires 中繼資料允許放棄支援某個 Python 版本,且不會對仍在使用該版本 Python 的使用者造成干擾。然而,一個常見的錯誤是遺漏或忘記更新該中繼資料。當發生此類錯誤時,專案通常只有三種選擇:

  • 透過某種機制阻止安裝該版本(目前唯一的機制是徹底刪除該版本)。
  • 將正常的版本作為較高版本號重新發布,然後將放棄支援的版本作為更高的版本號重新發布,並附帶正確的中繼資料。
  • 什麼都不做,並在文件中說明使用舊版 Python 的使用者必須手動排除該發布版本。

透過本 PEP,專案可以選擇第一種選項,但使用的機制能降低對「目前」正在成功使用該專案的使用者造成破壞的可能性。

規範

簡單儲存庫中的連結可以 (MAY) 包含一個 data-yanked 屬性,該屬性可以沒有值,或者具有一個任意字串作為值。data-yanked 屬性的存在應該 (SHOULD) 被解釋為該特定連結所指向的檔案已被「撤銷」,且除特定場景外,安裝程式通常不應選擇該檔案。

data-yanked 屬性的值(若存在)是一個任意字串,代表撤銷該檔案的原因。處理簡單儲存庫 API 的工具可以 (MAY) 將此字串顯示給終端使用者。

撤銷屬性在設定後並非不可變,未來可能會被取消(取消後也可能再次被設定)。因此,API 使用者必須 (MUST) 能夠處理撤銷檔案被「取消撤銷 (unyanked)」(甚至再次被撤銷)的情況。

安裝程式 (Installers)

理想的使用者體驗是:當檔案被撤銷後,如果有人嘗試直接安裝該檔案,它應該表現得像該檔案已被刪除一樣失敗。然而,如果使用者是在過去執行該操作,而現在電腦只是機械地遵循原始指令安裝已撤銷的檔案,則其運作應視為未被撤銷。

安裝程式必須 (MUST) 忽略已撤銷的發布版本(如果選定的限制條件可透過非撤銷版本滿足),並且可以 (MAY) 拒絕使用已撤銷的發布版本,即使這意味著無法滿足請求。實作應該 (SHOULD) 選擇遵循上述精神的策略,並防止對已撤銷的發布版本/檔案產生「新」的依賴。

這意味著具體如何處理取決於各個安裝程式,以決定最適合其安裝程式整體使用方式的方法。不過,我們建議兩種策略:

  1. 已撤銷的檔案總是會被忽略,除非它是唯一符合版本規範的檔案,且該規範使用 ==(不含任何使其成為範圍的修飾符,如 .*)或 === 鎖定為精確版本。除此以外,符合版本規範應根據 PEP 440(針對本地版本、補零等)處理。
  2. 已撤銷的檔案總是會被忽略,除非它是唯一符合鎖定檔(如 Pipfile.lockpoetry.lock)指定安裝的檔案。在此情況下,當從輸入檔案或指令建立或更新鎖定檔時,不應 (SHOULD NOT) 使用已撤銷的檔案。

無論安裝程式選擇哪種決定是否安裝已撤銷檔案的具體策略,安裝程式在決定安裝已撤銷檔案時應該 (SHOULD) 發出警告。該警告可以 (MAY) 利用 data-yanked 屬性的值(若有)來向使用者提供關於為何該檔案被撤銷的更具體反饋。

鏡像站 (Mirrors)

鏡像站通常可以透過以下兩種方式之一處理已撤銷的檔案:

  1. 他們可以選擇將其從簡單儲存庫 API 中完全刪除,僅顯示「活躍的」、未撤銷的檔案。
  2. 他們可以選擇包含已撤銷的檔案,並同時鏡像 data-yanked 屬性。

鏡像站不得 (MUST NOT) 在未同時鏡像 data-yanked 屬性的情況下鏡像已撤銷的檔案。

否決的想法

早期未經記載的簡單儲存庫 API 版本曾擁有特定版本的頁面,例如 /simple/<project>/<version>/。如果我們將其加回,已撤銷的檔案僅會出現在這些頁面上,而不會出現在無版本頁面上。然而,這會大幅降低簡單 API 的可快取性,並直接影響我們擴展其以處理所有傳入流量的能力。

本 PEP 的早期疊代版本曾將 data-yanked 屬性視為布林值。然而,經過討論認為,允許使用字串既能簡化實作,又能提供額外的通用功能,讓專案能說明撤銷發布版本的原因

另一個建議是在任意字串中保留某種語法,以便在未來有需要時能演進標準。然而,考量到未來我們可以隨時新增額外屬性,該想法已被拒絕,轉而傾向在有需要時使用額外屬性。

Warehouse/PyPI 實作說明

雖然本 PEP 在檔案層級實作撤銷,這主要歸因於簡單儲存庫 API 的現有結構,而非本 PEP 作出的特定決定。

在 Warehouse 中,使用者體驗將以撤銷或取消撤銷整個發布版本來實作,而非針對個別檔案的操作,該操作隨後會透過 API 以個別檔案撤銷的形式暴露出來。

其他儲存庫實作可以選擇以不同方式暴露此功能,或完全不暴露。

日誌處理

每當發布版本被撤銷時,系統將會記錄一筆日誌,並使用下列其中一種字串模式:

  • yank release
  • unyank release

在這兩種情況下,標準的日誌結構都會標明是哪個專案的哪個發布版本被撤銷或取消撤銷。


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

最後修改時間: 2025-02-01 08:55:40 GMT