Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

參與貢獻

感謝你有興趣貢獻 PyO3!歡迎所有人參與——請閱讀我們的行為準則以維持社群的正向與包容。

如果你正在尋找貢獻方向,請參考「開始參與貢獻」一節。如果你已找到想處理的特定議題並需要開發流程資訊,可參考「撰寫 Pull Request」一節。

若想熟悉程式碼庫,請參考 Architecture.md

開始參與貢獻

歡迎從你感興趣的 PyO3 領域加入。我們使用 GitHub issues 記錄所有錯誤與想法。若你想處理某個議題,請隨時申請指派。

你可以在這裡瀏覽 PyO3 非公開部分的 API。

以下章節也提供一些適合開始貢獻 PyO3 的具體想法。

設定開發環境

要開發 PyO3,你需要在系統中安裝 Python 與 Rust。

  • 我們建議使用 rustup 以便依專案選擇特定工具鏈。
  • 也強烈建議使用 Pyenv 以便選擇特定 Python 版本。
  • virtualenv 也可搭配或不搭配 Pyenv 使用特定已安裝的 Python 版本。
  • nox 用於自動化多項 CI 任務。

使用 nox 進行測試、lint 等

Nox 用於自動化多項 CI 任務,也可在本地用來處理程式撰寫時的驗證工作。我們建議透過 nox 執行這些動作,以使用我們偏好的設定選項。你可以用 pip 安裝 nox 到全域 Python:pip install nox,或(建議)使用 pipx 安裝:pip install pipxpipx install nox

我們提供的主要 nox 指令如下:

  • nox -s test 會執行完整的 Rust 與 Python 測試套件(>10 分鐘)
  • nox -s test-rust -- skip-full 會執行較短的 Rust 測試套件(2-3 分鐘)
  • nox -s ruff 會檢查 Python lint 並套用標準格式規則
  • nox -s rustfmt 會檢查基本 Rust lint 並套用標準格式規則
  • nox -s rumdl 會檢查指南中的 Markdown
  • nox -s clippy 會執行 clippy 提供 Rust 風格建議
  • nox -s bench 會對 Rust 程式碼進行效能基準測試
  • nox -s codspeed 會執行我們的 Rust 與 Python 效能測試套件
  • nox -s coverage 會分析測試覆蓋率並輸出 coverage.json(或使用 nox -s coverage lcov 輸出 lcov.info
  • nox -s check-guide 會使用 lychee 檢查指南與文件註解中的所有連結。

使用 nox -l 列出可執行的完整子指令。

UI 測試

PyO3 使用 trybuild 來開發 UI 測試,以擷取某些巨集功能的 Rust 編譯器錯誤訊息。

Rust 編譯器的錯誤輸出會因是否安裝 rust-src 元件而不同。PyO3 的 CI 已安裝 rust-src,所以若要讓本地 UI 測試輸出一致,你也需要安裝它:

rustup component add rust-src

由於這些 UI 測試有多種 feature 組合,當你要全部更新(例如因新版 Rust 編譯器)時,使用 update-ui-tests nox session 會很有幫助:

nox -s update-ui-tests

可協助的方式

協助使用者找出錯誤

PyO3 Discord 伺服器 非常活躍,許多使用者對 PyO3 甚至 Rust 都很新。協助他們除錯是熟悉 PyO3 程式碼庫的好方法。

協助他人常會暴露錯誤、文件不足與缺漏的 API。建議立刻在 GitHub 開 issue,讓解法得以規劃並實作!

實作可直接開發的議題

解法清楚且尚未有人處理的議題會使用 needs-implementer 標籤。

若你覺得解法不夠清楚也別擔心!PyO3 核心貢獻者很樂意針對你的任何疑問提供指導,幫助你完成解法。

協助撰寫優質文件

PyO3 有使用 mdbook 的使用者指南,以及一般的 Rust API 文件。我們的目標是讓兩者都詳盡、易懂且保持最新。歡迎提出拉取請求來修正錯字、調整措辭、補充範例等。

目前文件有一些需要協助的特定重點領域:

  • 與文件改進相關的議題會以 documentation 標籤追蹤。
  • 並非所有 API 在建立時都有文件或範例。我們的目標是讓所有 PyO3 API 都有文件(#306)。若你看到某個 API 缺少文件,請撰寫並開啟 PR!

若要建置文件(包含所有功能),請安裝 nox 並執行

nox -s docs -- open

文件測試

我們在文件中使用大量程式碼區塊。變更時請執行 cargo test --doc 以確認文件測試仍可正常運作,或執行 cargo test 來跑包含文件測試在內的所有 Rust 測試。文件測試指南請見 https://doc.rust-lang.org/rustdoc/documentation-tests.html。

建置指南

你可以使用 mdbook 在本地建置以預覽使用者指南。

首先安裝 mdbookmdbook-tabs 外掛,以及 nox。然後執行

nox -s build-guide -- --open

若要檢查指南中所有連結是否有效,請另行安裝 lychee 並改用 check-guide session:

nox -s check-guide

協助設計下一代 PyO3

尚未有明確解法的議題會使用 needs-design 標籤。

如果這些議題有你感興趣的,請加入該議題的討論!所有意見都很重要;若你還願意透過草稿 PR 嘗試 API 設計,那就更好了!

審查拉取請求

歡迎所有人對開放中的 PR 提出意見。請協助確保新的 PyO3 API 安全、效能良好、整潔且易用!

撰寫拉取請求

以下是撰寫 PR 時需要注意的幾點。

測試與持續整合

PyO3 儲存庫使用 GitHub Actions。若 CI 未通過,PR 會被阻止合併。所有 Rust 與 Python 程式碼都會檢查格式化、lint 與測試(若格式化失敗,流水線會提早中止以節省資源)。此外,Rust 程式碼中的所有警告都不被允許(使用 RUSTFLAGS="-D warnings")。

測試會在最新穩定版 Rust 編譯器與所有支援的 Python 版本上執行,並以最低支援的 Rust 版本測試 Python 3.9。

如果你新增了功能,請將其加入 Cargo.toml* 中的 full 功能集合,以便在 CI 中進行測試。

你可以用 nox 自行執行 CI 管線的各項元件,請見上方測試章節

變更文件化

我們使用 towncrier 為每次發行生成變更日誌。

要將你的變更納入發行說明,請在 newsfragments 目錄中建立一個或多個新聞項目。有效的新聞項目應儲存為 <PR>.<CATEGORY>.md,其中 <PR> 為拉取請求編號,<CATEGORY> 為下列其中之一:

  • packaging - 用於相依性變更與 Python/Rust 版本相容性變更
  • added - 用於新增功能
  • changed - 用於既有功能的修改或棄用
  • removed - 用於移除的功能
  • fixed - 用於被歸類為錯誤修復的「變更」功能

僅文件的 PR 不需要新聞項目;將 PR 標題以 docs: 開頭即可略過檢查。

風格指南

泛型程式碼

PyO3 有許多泛型 API 以提升易用性,但代價可能是泛型程式碼膨脹。在合理的情況下,請嘗試實作泛型函式的具體子部分。這有兩種形式:

  • 若該具體子部分無法被其他函式重用,請命名為 inner 並保留為函式內部的區域項。
  • 若該具體子部分會被其他函式重用,建議命名為 _foo,並將其放在原泛型函式 foo 的下方。

FFI 呼叫

PyO3 使用原始指標對 Python 的 C API 進行大量 FFI 呼叫。能避免時請避免在運算式中使用指向暫時值的指標:

// 危險
pyo3::ffi::Something(name.to_object(py).as_ptr());

// 因為以下重構會造成 use-after-free 錯誤:
let name = name.to_object(py).as_ptr();
pyo3::ffi::Something(name)

改用先綁定安全擁有的 PyObject 包裝,再傳給 ffi 函式:

let name: PyObject = name.to_object(py);
pyo3::ffi::Something(name.as_ptr())
// name 在離開作用域後會自動釋放

Python 與 Rust 版本支援政策

PyO3 旨在維持足夠的相容性,讓以 PyO3 建置的 Python 擴充能在多數常見軟體包管理系統中可行。

為了讓軟體包維護者的工作更簡單,PyO3 會盡可能承諾僅在同一時間調整最低支援的 Rust 與 Python 版本。此升級僅會出現在 0.x 版本,約每年一次,並在最舊支援的 Python 版本到達生命週期終點後進行。(可參考 https://endoflife.date/python 了解時間表。)

以下為各語言的相容性指引,所有 PR 都應遵循。

Python

PyO3 支援所有官方支援的 Python 版本,以及最新的 PyPy3 版本。這些版本都會在 CI 中測試。

新增對新 CPython 版本的支援

如果你打算新增對 CPython 預發行版本的支援,以下是(非完整)檢查清單:

  • 等待最後一個 alpha 版本(通常為 alpha7),因為 ABI 直到第一個 beta 版才有保證
  • .github/workflows/ci.yml 中新增 prerelease_ver-dev(例如 3.14-dev),並在 noxfile.pypyo3-ffi/Cargo.toml[package.metadata.cpython] 區段 max-version,以及 pyo3-ffi/build.rsmax 中提升版本
  • 為該版本新增 abi3-prerelease 功能(例如 abi3-py314
    • pyo3-build-config/Cargo.toml 中,將 abi3-most_current_stable 設為 [“abi3-prerelease”],並將 abi3-prerelease 設為 [“abi3”]
    • pyo3-ffi/Cargo.toml 中,將 abi3-most_current_stable 設為 [“abi3-prerelease”, “pyo3-build-config/abi3-most_current_stable”],並將 abi3-prerelease 設為 [“abi3”, “pyo3-build-config/abi3-prerelease”]
    • Cargo.toml 中,將 abi3-most_current_stable 設為 [“abi3-prerelease”, “pyo3-ffi/abi3-most_current_stable”],並將 abi3-prerelease 設為 [“abi3”, “pyo3-ffi/abi3-prerelease”]
  • 使用 #[cfg(Py_prerelease])(例如 #[cfg(Py_3_14)])與 #[cfg(not(Py_prerelease])) 來標示 CPython 穩定分支與預發行版之間的變更
  • 不要為 CPython 標頭中任何以 _ 開頭的函式、結構或全域變數新增 Rust 綁定
  • 如需協助請聯絡 @ngoldbaum 與 @davidhewitt

Rust

PyO3 旨在使用最新的 Rust 語言功能,以盡可能提高實作效率。

最低支援的 Rust 版本會在提升 Python 與 Rust 版本的發行時決定。當時設定的最低 Rust 版本不會高於當前 Debian、RHEL 與 Alpine Linux 發行版隨附的最低 Rust 版本。

CI 會測試最新穩定版 Rust 與最低支援 Rust 版本。由於 Rust 的穩定性保證,這足以確認中間所有版本的支援。

效能基準測試

PyO3 有兩組效能基準測試用於評估部分效能面向。目前測試套件還很小——若你願意協助擴充,歡迎新增基準測試並開 PR!

首先,在 pyo3-benches 子目錄中有以 Rust 為基礎的基準測試。你可以透過以下方式執行:

nox -s bench

其次,pytests 子目錄中包含一個以 Python 為基礎的基準測試。更多資訊請見此處

程式碼覆蓋率

你可以檢視 PyO3 測試涵蓋與未涵蓋的程式碼。我們目標是 100% 覆蓋率——如果你發現覆蓋不足,請檢查覆蓋率並補上測試!

  • 首先,請確保已安裝 llvm-cov cargo 外掛。在與 nox 搭配使用前,你可能需要先透過 cargo 執行外掛一次。
cargo install cargo-llvm-cov
cargo llvm-cov
  • 接著用以下方式產生 lcov.info 檔案
nox -s coverage -- lcov

你可以安裝 IDE 外掛來檢視覆蓋率。例如使用 VSCode:

  • 安裝 coverage-gutters 外掛。
  • 在 VSCode 的 settings.json 加入以下設定:
{
    "coverage-gutters.coverageFileNames": [
        "lcov.info",
        "cov.xml",
        "coverage.xml",
    ],
    "coverage-gutters.showLineCoverage": true
}
  • 你現在應該可以看到綠色高亮代表已測試的程式碼,紅色高亮代表未測試的程式碼。

贊助此專案

目前沒有代表 PyO3 接受贊助的官方組織。若你想為 PyO3 生態系提供較大規模的資金支持,請透過 GitHubDiscord 與我們聯絡,我們可進一步討論。

此外,我們部分維護者有個人的 GitHub 贊助頁面,若你願意支持將非常感謝: