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

Python 增強提案 (Python Enhancement Proposals)

PEP 632 – 棄用 distutils 模組

作者:
Steve Dower <steve.dower at python.org>
討論於:
Discourse 討論串
狀態:
最終 (Final)
類型:
標準軌跡 (Standards Track)
建立日期:
2020 年 9 月 3 日
Python 版本:
3.10
公告歷史:
2020 年 9 月 3 日,2021 年 1 月 22 日
決議:
Python-Dev 討論串

目錄

摘要

長期以來,distutils 模組 [1] 一直建議改用 setuptools 套件 [2]。Setuptools 最近已整合了 distutils 的完整副本,不再依賴標準函式庫 [3]。Pip 長期以來在安裝套件時,已經會悄悄地用 setuptools 取代 distutils,且 distutils 的文件自 2014 年(甚至更早)起就已聲明它正逐步淘汰。現在是時候將其從標準函式庫中移除。

動機

distutils [1] 是一組基本上未經妥善記錄且無人維護的工具集,用於封裝與發佈 Python 套件,包含原生擴充模組的編譯。它定義了一種描述 Python 發行版的配置格式,並提供將原始碼目錄轉換為原始碼發行版以及某些形式二進位發行版的工具。由於它身處標準函式庫中,許多更新只能隨大版本發布,且使用者無法依賴特定修復程式的即時發佈。

setuptools [2] 是一個基於 distutils 的增強功能,擁有更好的文件與維護。雖然它提供了非常相似的功能,但它更能支援早期 Python 版本的使用者,且能更快速地回應錯誤報告。Setuptools 中已經存在許多特定平台的增強功能,這些功能並未新增到 distutils 中,且 distutils 文件中長期以來一直建議優先使用 setuptools。

從歷史上看,setuptools 透過子類別化(subclassing)和 monkeypatching 來擴展 distutils,但現在已經採納了底層程式碼的副本 [3]。因此,對 distutils 的倒數第二大依賴項已經消失,無需再將其保留在標準函式庫中。

對 distutils 的最後一項依賴是 CPython 本身,它使用它來建置標準函式庫中的原生擴充模組(Windows 除外)。由於這是 CPython 的建置時依賴項,因此可以在不將其作為標準函式庫一部分的情況下,繼續針對此特定情況使用 distutils。

棄用與移除將使問題應在 setuptools 專案中修復這一點變得顯而易見,並將減少錯誤報告與不必要的測試維護來源。這也將有助於推動替代建置後端(build backends)的發展,現在透過 PEP 517 可以更容易地支援這些後端。

規範

在 Python 3.10 和 3.11 中,distutils 將被正式標記為棄用。所有已知問題將在此時關閉。`import distutils` 將引發棄用警告。可能會修復被視為阻礙發布的新問題,但不會新增對新工具或平台的支援。

在 Python 3.10 和 3.11 期間,標準函式庫內對 distutils 的使用可能會更改為使用替代 API。

在 Python 3.12 中,distutils 將不再由 `make install` 或任何第一方發行版安裝。第三方轉銷商不應再在其套件或儲存庫中包含 distutils。

本 PEP 不對遷移目前使用 distutils 的 CPython 建置流程部分做出規範。根據貢獻情況,此遷移可能在任何時候發生。

在 Python 3.12 啟動後,當 CPython 建置流程不再依賴於標準函式庫中的 distutils 時,整個 `Lib/distutils` 目錄和 `Lib/test/test_distutils.py` 檔案將從儲存庫中移除。

對 distutils 的其他引用將被清理。截至 Python 3.9 的初始版本,以下模組在程式碼或註解中存在引用

  • Lib/ctypes/util.py
  • Lib/site.py
  • Lib/sysconfig.py
  • Lib/_aix_support.py
  • Lib/_bootsubprocess.py
  • Lib/_osx_support.py
  • Modules/_decimal/tests/formathelper.py

CPython 中的以下工具也引用了 distutils。請注意,這些工具都不會隨 CPython 安裝

  • PC/layout (引用將被移除)
  • Tools/msi (引用將被移除)
  • Tools/peg_generator (將調整為使用不同的建置工具)
  • Tools/test2to3 (範例專案將被移除)

由於 distutils 程式碼已包含在 setuptools 中,因此無需以任何其他形式重新發布。需要該功能存取權的人應使用 setuptools 或替代的建置後端。

回溯相容性

從 Python 3.12 開始,匯入 distutils 的程式碼將不再運作。

建議的遷移路徑是使用 setuptools 中對應的(雖然不完全相同)匯入方式(參見 [5]),或遷移到替代的建置後端(參見 PEP 517)。

Setuptools 中已存在程式碼,可以透明地將使用 distutils 的 `setup.py` 檔案切換到其對應方式,因此大多數有效的建置腳本已知都可與 setuptools 配合使用。此類腳本可能需要更新其匯入語句。有關具體的遷移建議,請查閱 setuptools 文件。[5]

有些專案在 distutils 之上使用了替代的補丁集,特別是 numpy.distutils。[6] 我們已通知已知執行此操作的專案。

許多建置腳本使用自訂命令或範圍狹窄的補丁。由於這些套件已經受到 setuptools 取代 distutils 的影響,我們預計 distutils 的移除不會造成太大干擾。腳本可能仍需要更新以避免匯入 distutils。

參考實作

setuptools 48 版包含 distutils 的完整副本,因此不再依賴標準函式庫的版本。他們面臨的大多數實作問題都是由於 distutils 繼續存在於標準函式庫中,因此移除它將提高其實作的穩定性。

目前尚未有從標準函式庫中移除 distutils 的參考實作,也沒有在不依賴標準函式庫 distutils 的情況下進行 CPython 原生模組建置的實作。

遷移建議

附註

本節建議了一些受歡迎功能的替代方案,這些功能在本 PEP 中被正式棄用。它在撰寫時是準確的,但不會隨時更新。

對於這些模組或類型,`setuptools` 是最好的替代品

  • distutils.ccompiler
  • distutils.cmd.Command
  • distutils.command
  • distutils.config
  • distutils.core.Distribution
  • distutils.errors

對於這些模組或類型,請使用標準定義的 Python Packaging Authority 套件

  • `distutils.version` — 使用 `packaging` 套件

對於這些模組或函數,請使用所示的標準函式庫模組

  • `distutils.fancy_getopt` — 使用 `argparse` 模組
  • `distutils.spawn.find_executable` — 使用 `shutil.which` 函數
  • `distutils.spawn.spawn` — 使用 `subprocess.run` 函數
  • `distutils.sysconfig` — 使用 `sysconfig` 模組
  • `distutils.util.get_platform` — 使用 `platform` 模組

對於這些函數以及此處未提及的其他任何函數,您將需要自行重新實作該功能。舊版文件可在 https://docs.python.club.tw/3.9/distutils/apiref.html 找到

  • distutils.dir_util.create_tree
  • distutils.util.change_root
  • distutils.util.strtobool

否決的想法

棄用但不刪除

這種方法的主要問題在於 distutils 最常因為平台差異而中斷,這意味著若無維護,它將會與任何 Python 發行版脫節而停止運作。這使得程式庫無法可靠地檢測它們何時會停止運作。

相比之下,本 PEP 提出了一個提前知曉的具體日期,屆時 distutils 將停止運作,並承諾在此日期之前不會破壞 API。這為維護者提供了一個可預測的時間表,確保任何中斷都發生在使用者已經預期行為會發生變更的時候,並提供了一種可靠的檢測機制(具體來說,就是 `import distutils` 會引發錯誤)。

最後,只要 distutils 以任何形式保留在標準函式庫中,它就會干擾提供修補程式(shims)或替代方案的第三方套件,包括 setuptools。在已知的版本完全移除該套件,使得第三方能夠安全地使用替代品成為可能。

僅棄用類似 setuptools 的功能

這個建議假設有志願者來維護剩下的任何東西,但事實並非如此。它也暗示有人知道哪些功能應該保留,正如討論中所見,這一點完全不清楚。

distutils 中的大多數輔助函數已經有了受支援的(且改進後的)替代方案,通常在標準函式庫中,如果不破壞相容性,對舊版本幾乎無能為力。(而且任何要求維護者更新程式碼的中斷,本質上等同於要求他們匯入不同的函數。)

上一節的最後一點也適用於此。

參考文獻


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

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