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

型別 stub 產生(*.pyi 檔案)與內省

This feature is still in active development. See the related issue.

如需型別 stub 文件與在穩定版 PyO3 中的使用方式,請參考此頁

PyO3 正在開發產生型別 stub 檔案的支援。

其運作方式如下:

  1. PyO3 巨集(#[pyclass])會產生固定的 JSON 字串,並在啟用 experimental-inspect 功能時由 rustc 內嵌到編譯出的二進位檔。
  2. pyo3-introspection 軟體箱可解析產生的二進位檔,抽取 JSON 字串並產生 stub 檔案。
  3. [尚未完成] 例如 maturin 等建置工具在其 CLI API 中暴露 pyo3-introspection 功能。

例如,以下 Rust 程式碼

#[pymodule]
pub mod example {
    use pyo3::prelude::*;

    #[pymodule_export]
    pub const CONSTANT: &str = "FOO";

    #[pyclass(eq)]
    #[derive(Eq)]
    struct Class {
        value: usize
    }

    #[pymethods]
    impl Class {
        #[new]
        fn new(value: usize) -> Self {
            Self { value }
        }

        #[getter]
        fn value(&self) -> usize {
            self.value
        }
    }

    #[pyfunction]
    #[pyo3(signature = (arg: "list[int]") -> "list[int]")]
    fn list_of_int_identity(arg: Bound<'_, PyAny>) -> Bound<'_, PyAny> {
        arg
    }
}

會產生以下 stub 檔案:

import typing

CONSTANT: typing.Final = "FOO"

class Class:
    def __init__(self, value: int) -> None: ...

    @property
    def value(self) -> int: ...

    def __eq__(self, other: Class) -> bool: ...
    def __ne__(self, other: Class) -> bool: ...

def list_of_int_identity(arg: list[int]) -> list[int]: ...

新增的語法只有一項:#[pyo3(signature = ...)] 屬性現在可以包含型別標註,例如 #[pyo3(signature = (arg: "list[int]") -> "list[int]")](注意型別標註外層的 "")。當 PyO3 無法自行推導適當的型別標註時,這會很有用。

約束與限制

  • 需要啟用 experimental-inspect 功能才能產生內省片段。
  • 許多功能尚未實作。清單請參考相關議題
  • 內省僅適用於以內嵌 Rust 模組宣告的 Python 模組,使用函式宣告的模組不受支援。
  • 必須實作 FromPyObject::INPUT_TYPEIntoPyObject::OUTPUT_TYPE,PyO3 才能取得正確的輸入/輸出型別標註。
  • PyO3 無法內省 #[pymodule]#[pymodule_init] 函式的內容。若存在這些函式,模組會用一個假的 def __getattr__(name: str) -> Incomplete: ... 函式標記為 incomplete(遵循最佳實務)。