[PYTHON] [Rust] PyO3 returns an error

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.

Main paper

I think it will look like this [^ 1].

[^ 1]: This is an example code, so don't put in a rush like NaN? Orreturnunnecessary 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.

Commentary

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 ʻErrandreturn. 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.

References

Recommended Posts

[Rust] PyO3 returns an error
nltk.MaxentClassifier.train () throws an error.
WTForms always returns an error when AnyOf validation is SelectMultipleField
OperationalError: (psycopg2.OperationalError) gave an error
An error occurred in scikit-learn imputer