使用 pyo3 引发异常

Raising an exception with pyo3

如何正确引发异常?

我试过以下方法:

#[pymethods]
impl Foo {
    #[new]
    fn __new__(arg1: u8, ...) -> Self {
        if arg1 > LIMIT {
            let gil = Python::acquire_gil();
            let py = gil.python();
            PyErr::new::<exceptions::ValueError, _>("Parameter arg1 has invalid value").restore(py);
        }
        Foo {...}
    }

这与描述的实现方式完全相同 here

当我使用无效参数值创建 Foo 的实例时,会引发 SystemError 而不是 ValueError 并显示错误文本 <class 'Foo'> returned a result with an error set.

我每晚在 Linux 上使用 pyo3 0.11.1 和 Rust 1.47.0。

请注意,您 link 的示例是关于 main 中的错误管理。

我认为,正如 SystemError 所示,您正在同时设置错误和 return 值 。由于这些显然是排他性条件(提出 return 没有意义),Python 解释器错误。

作为 documented for ctors as well as noted after the first snippet of raising an exception,你应该 return 一个 [Py]Result,其中 Err 表示 pyo3 将为解释器设置的错误。

您可以使用 PyResult 的 returns 异常(将在 python 中引发):

#[pymethods]
impl Foo {
    #[new]
    fn __new__(arg1: u8, ...) -> PyResult<Self> {
        if arg1 > LIMIT {
            Err(exceptions::PyValueError::new_err("Parameter arg1 has invalid value"))
        } else {
            Ok(Foo {...})
        }
    }