You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: guide/src/type-stub.md
+6-1Lines changed: 6 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ It works using:
11
11
12
12
1. PyO3 macros (`#[pyclass]`) that generate constant JSON strings that are then included in the built binaries by rustc if the `experimental-inspect` feature is enabled.
13
13
2. The `pyo3-introspection` crate that can parse the generated binaries, extract the JSON strings and build stub files from it.
14
-
3.\[Not done yet\]Build tools like `maturin` exposing `pyo3-introspection` features in their CLI API.
14
+
3. Build tools like `maturin` exposing options in their CLI API to generate the stubs file.
The only piece of new syntax is that the `#[pyo3(signature = ...)]` attribute can contain type annotations like `#[pyo3(signature = (arg: "list[int]") -> "list[int]")]` (note the `""` around type annotations).
73
73
This is useful when PyO3 is not able to derive proper type annotations by itself.
74
74
75
+
To generate stubs file with `maturin` you can use `maturin generate-stubs --output stubs` that will build the project then generate the stubs in the `stubs` directory.
76
+
You can also directly integrate the stubs in the built wheels by doing `maturin build --generate-stubs` (works also with `maturin develop`).
77
+
78
+
PyO3 also provides the smaller `pyo3-introspection` binary that allows to generate stubs from an existing built extension using something like `pyo3-introspection my_module_binary.so my_module_name output` to introspect the `my_module_binary.so` dynamic library for the `my_module_name` Python module and generate its stubs in the `output` directory.
79
+
75
80
## Constraints and limitations
76
81
77
82
- The `experimental-inspect` feature is required to generate the introspection fragments.
//! Small CLI entry point to introspect a Python cdylib built using PyO3 and generate [type stubs](https://typing.readthedocs.io/en/latest/source/stubs.html).
2
+
3
+
use anyhow::{anyhow,Context,Result};
4
+
use pyo3_introspection::{introspect_cdylib, module_stub_files};
5
+
use std::path::Path;
6
+
use std::{env, fs};
7
+
8
+
fnmain() -> Result<()>{
9
+
let[_, binary_path, module_name, output_path] = env::args().collect::<Vec<_>>().try_into().map_err(|_| anyhow!("pyo3-introspection takes three arguments, the path of the binary to introspect, the name of the python module to introspect and and the path of the directory to write the stub to"))?;
10
+
let module = introspect_cdylib(&binary_path,&module_name)
11
+
.with_context(|| format!("Failed to introspect module {binary_path}"))?;
12
+
let actual_stubs = module_stub_files(&module);
13
+
for(path, module)in actual_stubs {
14
+
let file_path = Path::new(&output_path).join(path);
15
+
ifletSome(parent) = file_path.parent(){
16
+
fs::create_dir_all(parent).with_context(|| {
17
+
format!("Failed to create output directory {}", file_path.display())
18
+
})?;
19
+
}
20
+
fs::write(&file_path, module)
21
+
.with_context(|| format!("Failed to write module {}", file_path.display()))?;
0 commit comments