(_location: &str, _c: C, f: F)
| 210 | } |
| 211 | |
| 212 | pub unsafe fn handle_callback<F, T, C>(_location: &str, _c: C, f: F) -> C::R |
| 213 | where |
| 214 | F: FnOnce(Python) -> PyResult<T>, |
| 215 | F: panic::UnwindSafe, |
| 216 | C: CallbackConverter<T>, |
| 217 | { |
| 218 | let ret = panic::catch_unwind(|| { |
| 219 | let py = Python::assume_gil_acquired(); |
| 220 | match f(py) { |
| 221 | Ok(val) => C::convert(val, py), |
| 222 | Err(e) => { |
| 223 | e.restore(py); |
| 224 | C::error_value() |
| 225 | } |
| 226 | } |
| 227 | }); |
| 228 | match ret { |
| 229 | Ok(r) => r, |
| 230 | Err(err) => { |
| 231 | // Protect against panics in C::error_value() causing UB |
| 232 | let guard = AbortOnDrop("handle_panic() / C::error_value()"); |
| 233 | handle_panic(Python::assume_gil_acquired(), err); |
| 234 | let errval = C::error_value(); |
| 235 | mem::forget(guard); |
| 236 | errval |
| 237 | } |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | // This only needs `&dyn Any`, but we keep a `Box` all the way to avoid the |
| 242 | // risk of a subtle bug in the caller where `&Box<dyn Any>` is coerced to |
nothing calls this directly
no test coverage detected