型別 stub 產生(*.pyi 檔案)與內省
This feature is still in active development. See the related issue.
如需型別 stub 文件與在穩定版 PyO3 中的使用方式,請參考此頁
PyO3 正在開發產生型別 stub 檔案的支援。
其運作方式如下:
- PyO3 巨集(
#[pyclass])會產生固定的 JSON 字串,並在啟用experimental-inspect功能時由 rustc 內嵌到編譯出的二進位檔。 pyo3-introspection軟體箱可解析產生的二進位檔,抽取 JSON 字串並產生 stub 檔案。- [尚未完成] 例如
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_TYPE與IntoPyObject::OUTPUT_TYPE,PyO3 才能取得正確的輸入/輸出型別標註。 - PyO3 無法內省
#[pymodule]與#[pymodule_init]函式的內容。若存在這些函式,模組會用一個假的def __getattr__(name: str) -> Incomplete: ...函式標記為 incomplete(遵循最佳實務)。