pyproject.toml

版本 10.0 中新增。

PEP 518 中首次導入,並在 PEP 517PEP 621PEP 660 中進一步擴充之後,現代 Python 套件可以包含 pyproject.toml 檔案。此檔案包含建置系統需求和資訊,pip 會使用它們來建置套件。

建置流程

建置套件的整體流程為

  • 建立一個隔離的建置環境。

  • 在建置環境中填入建置相依關係。

  • 在必要且可行的情況下產生套件的元資料。

  • 為套件產生一個輪子 (wheel)。

輪子可用於在必要的情況下進行安裝。

建置隔離

為了使用此介面建置套件,pip 會使用一個「隔離環境」。也就是說,pip 會將建置時間的 Python 相依關係安裝在一個暫存目錄中,而這個目錄會被加入到建置指令的 sys.path 中。這可確保建置需求會獨立於使用者的執行時間環境來處理。

舉例來說,即使使用者已安裝較新版本的 setuptools,仍然可以安裝需要較舊版本的 setuptools 來建置專案(而且不會在沒有提示的情況下取代該版本)。

建置時間相依關係

PEP 518 中導入的 build-system.requires 鍵是 pyproject.toml 檔案中套件的建置時間相依關係需求規格的列表。

[build-system]
requires = ["setuptools ~= 58.0", "cython ~= 0.29.0"]

建置後端也可以使用 PEP 517get_requires_for_build_wheel 鉤子來提供動態計算的建置相依關係。pip 會呼叫此鉤子,且它所描述的相依關係也會安裝在建置環境中。舉例來說,較新的 setuptools 版本會透過此鉤子將 setup_requires 的內容顯示給 pip。

建置時間需求規格遵循 PEP 508,因此可以參照带有 URL 的套件。例如

[build-system]
requires = ["setuptools @ git+https://github.com/pypa/setuptools.git@main"]

元資料產生

在版本 19.0 中加入。

在建立環境並完成建立時間依賴關係後,pip 通常需要套件的元資料(名稱、版本、依賴關係等資訊)。

如果 PEP 517prepare_metadata_for_build_wheel 勾子由建置後端提供,將會使用該勾子來產生套件的元資料。否則會產生輪件(如下所述),並使用該輪件中包含的元資料。

輪件產生

在版本 19.0 中加入。

為了產生輪件,pip 使用 PEP 517 build_wheel,建置後端必須提供這個勾子。建置後端將會產生輪件,這可能包含編譯以 C/C++(或其他語言)編寫的擴充程式碼。

使用這種機制產生的輪件可以 快取 以重複使用,以加快未來的安裝速度。

可編輯安裝

在版本 21.3 中加入。

為了執行可編輯安裝,pip 將使用 PEP 660 build_wheel_for_editable,建置後端必須提供這個勾子。使用這種機制產生的輪件不會快取。

相容性後備

如果建置後端遺漏這個勾子而且專案中有 setup.py 檔案,pip 將會採用舊制的 setup.py 為基礎的可編輯安裝。

這被認為是一個權宜解決方案,直到 setuptools 加入對 PEP 660 的支援。屆時,這個功能將會移除,並遵循 pip 的一般 淘汰政策

後端組態

建置後端有能力接受組態設定,這些設定可以改變建置的執行方式。這些設定呈現在一系列 key=value 成對項目中。使用者可以使用 --config-settings 命令列選項來提供組態設定(可以提供多次,以指定多個設定)。

傳入的設定組態會傳遞至每個後端掛勾呼叫。

透過 --config-settings 命令列選項(或等值的環境變數或設定檔項目)提供的設定組態會傳遞至明確提供做為 pip 命令列參數的必要組件版本中。它們不會傳遞至相依項目的版本中,也不會傳遞至必要組件檔案中提供的必要組件版本中。

版本輸出

後端版本應負責確保輸出使用正確的編碼,如 PEP 517 中所述。此步驟可能需要處理 與 pip 進行舊版版本製作時所遇到的相同挑戰

備援行為

警告

下列摘錄僅說明備援行為。如要取得可與 setuptools 搭配使用的 pyproject.toml 有效範例,請參閱 setuptools 文件

如果專案沒有包含 build-system 區塊的 pyproject.toml 檔案,則會假設它具有下列後端設定

[build-system]
requires = ["setuptools>=40.8.0"]
build-backend = "setuptools.build_meta:__legacy__"

如果專案具有 build-system 區塊但沒有 build-backend,則

  • 預期會將 setuptools 納入為版本必要組件。如果 setuptools 的可用版本不夠新,則會回報錯誤。

  • 將使用 setuptools.build_meta:__legacy__ 版本後端。

停用版本隔離

這可以使用 --no-build-isolation 旗標停用 -- 提供這個旗標的使用者需負責確保建置環境適當管理,包括確保已安裝所有必要的建置時間相依項,因為在傳遞這個旗標時,pip 不會管理建置時間相依項。

歷史備註

由於此功能是漸進式推出的,因此已進行多項顯著的變更與改進。

  • setuptools 40.8.0 是第一個提供 PEP 517 後端的 setuptools 版本,它可緊密模擬直接執行 setup.py

  • 在 pip 18.0 之前,pip 僅支援從輪子中安裝建置需求,不支援使用環境標記和額外元件(只支援版本規格說明符)。

  • 在 pip 18.1 之前,使用 .pth 檔案的建置相依性並未適當支援;因此,命名空間套件無法在 Python 3.2 之前版本使用。