macro_rules! py_fn { ($py:expr, $f:ident $plist:tt ) => { ... }; ($py:ident, $f:ident $plist:tt -> $ret:ty { $($body:tt)* } ) => { ... }; }
Expand description
Creates a Python callable object that invokes a Rust function.
There are two forms of this macro:
py_fn!(py, f(parameter_list))
py_fn!(py, f(parameter_list) -> PyResult<T> { body })
both forms return a value of type PyObject
.
This python object is a callable object that invokes
the Rust function when called.
When called, the arguments are converted into
the Rust types specified in the parameter list.
See py_argparse!()
for details on argument parsing.
Form 1:
py
must be an expression of typePython
f
must be the name of a function that is compatible with the specified parameter list, except that a single parameter of typePython
is prepended. The function must returnPyResult<T>
for someT
that implementsToPyObject
.
Form 2:
py
must be an identifier that refers to aPython
value. The function body will also have access to aPython
variable of this name.f
must be an identifier.- The function return type must be
PyResult<T>
for someT
that implementsToPyObject
.
§Errors
- If argument parsing fails, the Rust function will not be called and an
appropriate Python exception is raised instead (usually
TypeError
when the Python value does not match the expected type; the implementation ofFromPyObject
for your type may document additional errors). - If the Rust function panics, a Python
SystemError
will be raised.
§Example
use cpython::{Python, PyResult, PyErr, PyDict, py_fn};
use cpython::{exc};
fn multiply(py: Python, lhs: i32, rhs: i32) -> PyResult<i32> {
match lhs.checked_mul(rhs) {
Some(val) => Ok(val),
None => Err(PyErr::new_lazy_init(py.get_type::<exc::OverflowError>(), None))
}
}
fn main() {
let gil = Python::acquire_gil();
let py = gil.python();
let dict = PyDict::new(py);
dict.set_item(py, "multiply", py_fn!(py, multiply(lhs: i32, rhs: i32))).unwrap();
py.run("print(multiply(6, 7))", None, Some(&dict)).unwrap();
}