##// END OF EJS Templates
rust-pyo3: error propagation for UnsafePyLeaked wrapping a result...
Georges Racinet -
r53426:bd65cb04 default
parent child Browse files
Show More
@@ -212,3 +212,41 pub(crate) unsafe fn proxy_index_extract
212 212 };
213 213 Ok(py_shared.inner)
214 214 }
215
216 /// Error propagation for an [`UnsafePyLeaked`] wrapping a [`Result`]
217 ///
218 /// TODO (will consider when implementing UnsafePyLeaked in PyO3):
219 /// It would be nice for UnsafePyLeaked to provide this directly as a variant
220 /// of the `map` method with a signature such as:
221 ///
222 /// ```
223 /// unsafe fn map_or_err(&self,
224 /// py: Python,
225 /// f: impl FnOnce(T) -> Result(U, E),
226 /// convert_err: impl FnOnce(E) -> PyErr)
227 /// ```
228 ///
229 /// This would spare users of the `cpython` crate the additional `unsafe` deref
230 /// to inspect the error and return it outside `UnsafePyLeaked`, and the
231 /// subsequent unwrapping that this function performs.
232 #[allow(dead_code)]
233 pub(crate) fn py_leaked_or_map_err<T, E: std::fmt::Debug + Copy>(
234 py: cpython::Python,
235 leaked: cpython::UnsafePyLeaked<Result<T, E>>,
236 convert_err: impl FnOnce(E) -> PyErr,
237 ) -> PyResult<cpython::UnsafePyLeaked<T>> {
238 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
239 if let Err(e) = *unsafe {
240 leaked
241 .try_borrow(py)
242 .map_err(|e| from_cpython_pyerr(py, e))?
243 } {
244 return Err(convert_err(e));
245 }
246 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
247 Ok(unsafe {
248 leaked.map(py, |res| {
249 res.expect("Error case should have already be treated")
250 })
251 })
252 }
General Comments 0
You need to be logged in to leave comments. Login now