pyO3 和 Panics

huangapple go评论56阅读模式
英文:

pyO3 and Panics

问题

我已经为您翻译好了所需的内容:

我已经使用pyO3将一些Python代码重写成了Rust。我遇到了这样一种情况:我的Rust代码可能会在我使用的第三方Rust库中的某个地方发生panic。对我来说,最简单的方法是在Python中捕获那个panic,然后退回到速度较慢但更可靠的Python方法。失败的情况很少,以至于退回到Python仍然比仅使用Python更有效率。有没有办法处理Rust的panic呢?从我所了解的情况来看,答案可能是“不行”,但我还是希望能有办法!

下面是我所说的内容的简化示例。非常感谢任何帮助!

(我知道我可以追踪每次panic的具体原因,但我认为这个问题仍然有一定价值。)

**lib.rs**

```rust
use numpy::{IntoPyArray, PyArray1, PyReadonlyArray1};
use pyo3::{pymodule, types::PyModule, PyResult, Python};

#[pymodule]
fn can_panic(_py: Python, m: &PyModule) -> PyResult<()> {
    #[pyfn(m)]
    fn can_panic<'py>(
        py: Python<'py>,
        arr: PyReadonlyArray1<i64>,
    ) -> &'py PyArray1<bool> {
        let my_arr = arr.as_array();
        for v in my_arr {
            if v == &-1 {
                panic!("Hey, you can't do that!");
            }
        }
        vec![true; my_arr.len()].into_pyarray(py)
    }

    Ok(())
}

Cargo.toml

[package]
name = "can_panic"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "can_panic"
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.18.3", features = ["extension-module", "anyhow"] }
numpy = "0.18.0"
nalgebra = "0.32.2"

testing.py

import numpy as np
import can_panic

print("Staring filtering")

print(can_panic.can_panic(np.array([1, 2, 3], dtype="int64")))

print("Done filtering")

print("Staring Filtering")

try:
    print(can_panic.can_panic(np.array([-1, 2, 3], dtype="int64")))
except Exception:
    print("didn't work")
    # call Python equivalent

print("Done filtering")

output

Staring filtering
[ True  True  True]
Done filtering
Staring Filtering
thread '<unnamed>' panicked at 'Hey, you can't do that!', src/lib.rs:16:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Traceback (most recent call last):
  File "(snip...)/can_panic/testing.py", line 13, in <module>
    print(can_panic.can_panic(np.array([-1, 2, 3], dtype="int64")))
pyo3_runtime.PanicException: Hey, you can't do that!

请注意,这只是您提供的代码的翻译版本,没有额外的内容。如果您需要进一步的帮助,请随时提问。

英文:

I have re-written some Python into Rust using pyO3. I have a situation where my Rust code can panic somewhere in a third party Rust library I use. The simplest thing for me would be to catch that panic in Python-land and fall back to the slower (but more resilient) Python method. The failure is rare enough that falling back to Python is still more efficient than only-Python. Is there any way to deal with the Rust panic? From what I've read the answer is probably "no," but I'm hoping!

Below is simplified example of what I mean. Any help is appreciated!

(I know I could/can track down the specific reason for each panic, but I think this question has merit anyway.)

lib.rs

use numpy::{IntoPyArray, PyArray1, PyReadonlyArray1};
use pyo3::{pymodule, types::PyModule, PyResult, Python};

#[pymodule]
fn can_panic(_py: Python, m: &amp;PyModule) -&gt; PyResult&lt;()&gt; {
    #[pyfn(m)]
    fn can_panic&lt;&#39;py&gt;(
        py: Python&lt;&#39;py&gt;,
        arr: PyReadonlyArray1&lt;i64&gt;,
    ) -&gt; &amp;&#39;py PyArray1&lt;bool&gt; {
        let my_arr = arr.as_array();
        for v in my_arr {
            if v == &amp;-1 {
                panic!(&quot;Hey, you can&#39;t do that!&quot;);
            }
        }
        vec![true; my_arr.len()].into_pyarray(py)
    }

    Ok(())
}

Cargo.toml

[package]
name = &quot;can_panic&quot;
version = &quot;0.1.0&quot;
edition = &quot;2021&quot;

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = &quot;can_panic&quot;
crate-type = [&quot;cdylib&quot;]

[dependencies]
pyo3 = { version = &quot;0.18.3&quot;, features = [&quot;extension-module&quot;, &quot;anyhow&quot;] }
numpy = &quot;0.18.0&quot;
nalgebra = &quot;0.32.2&quot;

testing.py

import numpy as np
import can_panic

print(&quot;Staring filtering&quot;)

print(can_panic.can_panic(np.array([1, 2, 3], dtype=&quot;int64&quot;)))

print(&quot;Done filtering&quot;)

print(&quot;Staring Filtering&quot;)

try:
    print(can_panic.can_panic(np.array([-1, 2, 3], dtype=&quot;int64&quot;)))
except Exception:
    print(&quot;didn&#39;t work&quot;)
    # call Python equivalent

print(&quot;Done filtering&quot;)

output

Staring filtering
[ True  True  True]
Done filtering
Staring Filtering
thread &#39;&lt;unnamed&gt;&#39; panicked at &#39;Hey, you can&#39;t do that!&#39;, src/lib.rs:16:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Traceback (most recent call last):
  File &quot;(snip...)/can_panic/testing.py&quot;, line 13, in &lt;module&gt;
    print(can_panic.can_panic(np.array([-1, 2, 3], dtype=&quot;int64&quot;)))
pyo3_runtime.PanicException: Hey, you can&#39;t do that!

答案1

得分: 1

Your except doesn't work because as pyo3 documents PanicException derives from BaseException (like SystemExit or KeyboardError) as it's not necessarily safe (given not all rust code is panic safe, pyo3 does not assume a rust-level panic is innocuous).

Your options then would be, in decreasing order of desirability (as far as I'm concerned):

  • improve the third-party library or your call to it so it does not panic
  • use catch_unwind on the Rust side, and convert the panic to a more classic Error
  • catch the PanicException specifically, which is not great (and possibly not easy) as you probably don't want to catch BaseException
英文:

Your except doesn't work because as pyo3 documents PanicException derives from BaseException (like SystemExit or KeyboardError) as it's not necessarily safe (given not all rust code is panic safe, pyo3 does not assume a rust-level panic is innocuous).

Your options then would be, in decreasing order of desirability (as far as I'm concerned):

  • improve the third-party library or your call to it so it does not panic
  • use catch_unwind on the Rust side, and convert the panic to a more classic Error
  • catch the PanicException specifically, which is not great (and possibly not easy) as you probably dont' want to catch BaseException

huangapple
  • 本文由 发表于 2023年6月1日 05:14:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76377350.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定