Skip to content

Commit

Permalink
Extend pyproject.toml example to include a Rust entry-point
Browse files Browse the repository at this point in the history
  • Loading branch information
abravalheri committed Aug 5, 2023
1 parent 4dfe009 commit 103993f
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 11 deletions.
1 change: 1 addition & 0 deletions examples/hello-world-pyprojecttoml/noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def test(session: nox.Session):
session.run("print-hello")
# Test script wrapper for Python entry-point
session.run("sum-cli", "5", "7")
session.run("rust-demo", "5", "7")
# Test library
session.run("pytest", "tests", *session.posargs)
session.run("python", "-c", "from hello_world import _lib; print(_lib)")
29 changes: 19 additions & 10 deletions examples/hello-world-pyprojecttoml/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
[build-system]
requires = ["setuptools", "wheel", "setuptools-rust"]
requires = ["setuptools", "setuptools-rust"]
build-backend = "setuptools.build_meta"

[project]
name = "hello-world"
version = "1.0"

[project.scripts] # Python entry-point wrapper to be installed in `$venv/bin`
sum-cli = "hello_world.sum_cli:main"
[project.scripts]
# Python entry-point wrapper to be installed in `$venv/bin`
sum-cli = "hello_world.sum_cli:main" # Python function that uses Rust
rust-demo = "hello_world._lib:demo" # Rust function that uses Python

[tool.setuptools.packages] # pure Python packages/modules
[tool.setuptools.packages]
# Pure Python packages/modules
find = { where = ["python"] }

[[tool.setuptools-rust.ext-modules]]
target = "hello_world._lib" # private module to be nested into Python package
py-limited-api = "auto"
args = ["--profile", "release-lto"]
# Private Rust extension module to be nested into Python package
target = "hello_world._lib" # The last part of the name (e.g. "_lib") has to match lib.name in Cargo.toml,
# but you can add a prefix to nest it inside of a Python package.
py-limited-api = "auto" # Default value, can be omitted
binding = "PyO3" # Default value, can be omitted
# See reference for RustExtension in https://setuptools-rust.readthedocs.io/en/latest/reference.html

[[tool.setuptools-rust.binaries]] # executable to be installed in `$venv/bin`
target = "print-hello"
args = ["--profile", "release-lto"]
[[tool.setuptools-rust.binaries]]
# Rust executable to be installed in `$venv/bin`
target = "print-hello" # Needs to match bin.name in Cargo.toml
args = ["--profile", "release-lto"] # Extra args for Cargo
# See reference for RustBin in https://setuptools-rust.readthedocs.io/en/latest/reference.html
# Note that you can also use Python entry-points as alternative to Rust binaries
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import argparse
import sys

from . import sum_as_string
from ._lib import sum_as_string


def main():
Expand Down
19 changes: 19 additions & 0 deletions examples/hello-world-pyprojecttoml/rust/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
use pyo3::prelude::*;
use std::env;

/// Formats the sum of two numbers as string.
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}

/// Calls Python (see https://pyo3.rs for details)
#[pyfunction]
fn demo(py: Python) -> PyResult<()> {
let argv = env::args().collect::<Vec<_>>();
println!("argv = {:?}", argv);
// argv[0]: Python path, argv[1]: program name, argv[2..]: given args

let numbers: Vec<i32> = argv[2..].iter().map(|s| s.parse().unwrap()).collect();

Python::with_gil(|py| {
let python_sum = PyModule::import(py, "builtins")?.getattr("sum")?;
let total: i32 = python_sum.call1((numbers,))?.extract()?;
println!("sum({}) = {:?}", argv[2..].join(", "), total);
Ok(())
})
}

/// A Python module implemented in Rust. The name of this function must match
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
/// import the module.
#[pymodule]
fn _lib(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
m.add_function(wrap_pyfunction!(demo, m)?)?;
Ok(())
}

0 comments on commit 103993f

Please sign in to comment.