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: &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!