All Rust stack frames which have FFI stack frames directly under them should be guarded by a catch_unwind to ensure that it is impossible to accidentally panic back into Python’s stack frames. It is undefined behaviour to panic-unwind into stack frames of functions written in other languages, which makes any Rust-written python method that may panic for any reason – pyo3 is not exempt – unsound.
Alternatively, users of pyo3 should be instructed to wrap their code into catch_unwind and handle this scenario on their own. In that case the requirement to not panic without catch_unwind should be thoroughly documented.
For reference, I encountered this issue by experimenting with errors and doing something along the lines of:
#[pyclass]
struct Exception {};
// In a `PyResult` returning method
return Err(PyErr::new::<Exception, _>("hello"));
Where PyErr panicked because Exception is not a valid Exception type.