I was writing a library for Python using PyO3 in Rust, but when there is a constraint on the input of a function (for example, the square root must be non-negative) and that constraint is not met. I didn't know how to return an error (ValueError
) and it took a lot of time. I'm sure I'll end up googled the same thing again in about half a year, but that's a hassle, so I'll summarize what I found.
I think it will look like this [^ 1].
[^ 1]: This is an example code, so don't put in a rush like NaN
? Orreturn
unnecessary if you use ʻif else`.
#[pyfunction]
fn sqrt_rs(value: f64) -> PyResult<f64> {
if value.is_sign_negative() {
return Err(pyo3::exceptions::ValueError::py_err(
"Negative value entered for sqrt.Please enter a non-negative value."
);
}
Ok(value.sqrt())
}
There are many other error types defined in pyo3 :: executions
. The usage is all the same, just call the py_err
function.
Functions exposed on the Python side return a PyResult <T>
type on the Rust side, but what is this type? PyResult <T> = Result <T, PyErr>
. So if an error occurs, You could just create an instance of type PyErr
, wrap it in ʻErrand
return. So what is type
PyErr`?
PyO3 defines various Python error types (such as ValueError
and TypeError
) in the module pyo3 :: exceptions
. These are all different types on the Rust side, so it's a bit cumbersome to handle as is. So PyO3 provides a wrapper structure PyErr
that holds various error types and their values. Each error type is accompanied by a py_err
function that returns a PyErr
type, which is an argument. You can get a PyErr
instance that wraps the desired error type instance by passing that value as.