rust-pyo3: generic borrows of UnsafePyLeaked with error treatment
authorGeorges Racinet <georges.racinet@cloudcrane.io>
Sat, 07 Dec 2024 18:24:24 +0100
changeset 52530 736551565871
parent 52529 bd65cb043aa5
child 52531 4c9e31984b3a
rust-pyo3: generic borrows of UnsafePyLeaked with error treatment Maybe we will find later a more pleasant way to express safety. Meanwhile, these helpers are useful because of the proper error propagation, and will help to avoid too much cruft in the caller code.
rust/hg-pyo3/src/convert_cpython.rs
--- a/rust/hg-pyo3/src/convert_cpython.rs	Sat Dec 07 18:18:09 2024 +0100
+++ b/rust/hg-pyo3/src/convert_cpython.rs	Sat Dec 07 18:24:24 2024 +0100
@@ -213,6 +213,40 @@
     Ok(py_shared.inner)
 }
 
+/// Generic borrow of [`cpython::UnsafePyLeaked`], with proper mapping.
+///
+/// # Safety
+///
+/// The invariants to maintain are those of the underlying
+/// [`UnsafePyLeaked::try_borrow`]: the caller must not leak the inner
+/// static reference. It is possible, depending on `T` that such a leak cannot
+/// occur in practice. We may later on define a marker trait for this,
+/// which will allow us to make declare this function to be safe.
+#[allow(dead_code)]
+pub(crate) unsafe fn py_leaked_borrow<'a, 'py: 'a, T>(
+    py: &impl WithGIL<'py>,
+    leaked: &'a cpython::UnsafePyLeaked<T>,
+) -> PyResult<cpython::PyLeakedRef<'a, T>> {
+    let py = cpython_handle(py);
+    leaked.try_borrow(py).map_err(|e| from_cpython_pyerr(py, e))
+}
+
+/// Mutable variant of [`py_leaked_borrow`]
+///
+/// # Safety
+///
+/// See [`py_leaked_borrow`]
+#[allow(dead_code)]
+pub(crate) unsafe fn py_leaked_borrow_mut<'a, 'py: 'a, T>(
+    py: &impl WithGIL<'py>,
+    leaked: &'a mut cpython::UnsafePyLeaked<T>,
+) -> PyResult<cpython::PyLeakedRefMut<'a, T>> {
+    let py = cpython_handle(py);
+    leaked
+        .try_borrow_mut(py)
+        .map_err(|e| from_cpython_pyerr(py, e))
+}
+
 /// Error propagation for an [`UnsafePyLeaked`] wrapping a [`Result`]
 ///
 /// TODO (will consider when implementing UnsafePyLeaked in PyO3):