Skip to content

Commit

Permalink
Merge pull request #4 from Jij-Inc/simplify
Browse files Browse the repository at this point in the history
Simplify example crate
  • Loading branch information
termoshtt authored Jan 5, 2024
2 parents 796a45d + e0ad030 commit 911b75d
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: run
args: --bin stub_gen --features stub_gen
args: --bin stub_gen

- name: Check if stub file is up to date
run: git diff --exit-code
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,82 @@

Python stub file (`*.pyi`) generator for PyO3 based projects.

# Usage

This crate provides a procedural macro `#[gen_stub_pyfunction]` and others to generate a Python stub file.
It is used with PyO3's `#[pyfunction]` macro. Let's consider a simple example PyO3 project:

```rust:no_run
use pyo3::prelude::*;
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}
#[pymodule]
fn pyo3_stub_gen_testing(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
Ok(())
}
```

To generate a stub file for this project, please modify it as follows:

```rust:no_run
use pyo3::prelude::*;
use pyo3_stub_gen::{derive::gen_stub_pyfunction, StubInfo};
use std::{env, path::*};
#[gen_stub_pyfunction] // Proc-macro attribute to register a function to stub file generator.
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}
#[pymodule]
fn pyo3_stub_gen_testing(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
Ok(())
}
/// Create stub file generator `StubInfo` for this project
pub fn stub_info() -> pyo3_stub_gen::Result<StubInfo> {
let manifest_dir: &Path = env!("CARGO_MANIFEST_DIR").as_ref();
// Get Python project name from pyproject.toml
StubInfo::from_pyproject_toml(manifest_dir.join("pyproject.toml"))
}
```

And then, create an executable target in `src/bin/stub_gen.rs`:

```rust:no_run
use pyo3_stub_gen::Result;
fn main() -> Result<()> {
let stub = pyo3_stub_gen_testing::stub_info()?;
stub.generate_single_stub_file(env!("CARGO_MANIFEST_DIR"))?;
Ok(())
}
```

and add `rlib` in addition to `cdylib` in `[lib]` section of `Cargo.toml`:

```toml
[lib]
crate-type = ["cdylib", "rlib"]
```

This target generates a stub file `${CARGO_MANIFEST_DIR}/pyo3_stub_gen_testing.pyi` when executed.

```shell
cargo run --bin stub_gen
```

The stub file is automatically found by `maturin`, and it is included in the wheel package. See also the [maturin document](https://www.maturin.rs/project_layout#adding-python-type-information) for more details.

There is a working example at [pyo3-stub-gen-testing](./pyo3-stub-gen-testing/) directory with generated stub file [pyo3_stub_gen_testing.pyi](./pyo3-stub-gen-testing/pyo3_stub_gen_testing.pyi).

# License

© 2024 Jij Inc.
Expand Down
10 changes: 1 addition & 9 deletions pyo3-stub-gen-testing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,5 @@ edition = "2021"
crate-type = ["cdylib", "rlib"]

[dependencies]
pyo3-stub-gen = { workspace = true, optional = true }
pyo3-stub-gen.workspace = true
pyo3.workspace = true

[features]
stub_gen = ["pyo3-stub-gen"]

[[bin]]
name = "stub_gen"
path = "src/bin/stub_gen.rs"
required-features = ["stub_gen"]
6 changes: 0 additions & 6 deletions pyo3-stub-gen-testing/pyo3_stub_gen_testing.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ from enum import Enum, auto
def sum_as_string(a,b) -> str:
r"""
Returns the sum of two numbers as a string.
Test of running doc-test
```rust
assert_eq!(2 + 2, 4);
```
"""
...

29 changes: 13 additions & 16 deletions pyo3-stub-gen-testing/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
#[doc = include_str!("../../README.md")]
mod readme {}

use pyo3::prelude::*;
use pyo3_stub_gen::{derive::gen_stub_pyfunction, StubInfo};
use std::{env, path::*};

#[cfg(feature = "stub_gen")]
use pyo3_stub_gen::derive::*;
/// Gather information to generate stub files
pub fn stub_info() -> pyo3_stub_gen::Result<StubInfo> {
let manifest_dir: &Path = env!("CARGO_MANIFEST_DIR").as_ref();
StubInfo::from_pyproject_toml(manifest_dir.join("pyproject.toml"))
}

/// Returns the sum of two numbers as a string.
///
/// Test of running doc-test
///
/// ```rust
/// assert_eq!(2 + 2, 4);
/// ```
#[cfg_attr(feature = "stub_gen", gen_stub_pyfunction)]
#[gen_stub_pyfunction]
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}

/// Initializes the Python module
#[pymodule]
fn pyo3_stub_gen_testing(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
Ok(())
}

#[cfg(feature = "stub_gen")]
pub fn stub_info() -> pyo3_stub_gen::Result<pyo3_stub_gen::StubInfo> {
use std::{env, path::*};
let manifest_dir: &Path = env!("CARGO_MANIFEST_DIR").as_ref();
pyo3_stub_gen::StubInfo::from_pyproject_toml(manifest_dir.join("pyproject.toml"))
}

/// Test of unit test for testing link problem
#[cfg(test)]
mod test {
#[test]
Expand Down

0 comments on commit 911b75d

Please sign in to comment.