From cacdaeafd309334565867235946c7989f95fb600 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Wed, 20 Mar 2024 09:14:01 +0000 Subject: [PATCH] add Bound::as_unbound --- src/instance.rs | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/instance.rs b/src/instance.rs index 024a9fe5b51..6b05da54c2c 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -465,6 +465,13 @@ impl<'py, T> Bound<'py, T> { unsafe { Py::from_non_null(non_null) } } + /// Removes the connection for this `Bound` from the GIL, allowing + /// it to cross thread boundaries, without transferring ownership. + #[inline] + pub fn as_unbound(&self) -> &Py { + &self.1 + } + /// Casts this `Bound` as the corresponding "GIL Ref" type. /// /// This is a helper to be used for migration from the deprecated "GIL Refs" API. @@ -521,11 +528,11 @@ impl<'py, T> Borrowed<'_, 'py, T> { /// # fn main() -> PyResult<()> { /// Python::with_gil(|py| -> PyResult<()> { /// let tuple = PyTuple::new_bound(py, [1, 2, 3]); - /// + /// /// // borrows from `tuple`, so can only be /// // used while `tuple` stays alive /// let borrowed = tuple.get_borrowed_item(0)?; - /// + /// /// // creates a new owned reference, which /// // can be used indendently of `tuple` /// let bound = borrowed.to_owned(); @@ -1958,10 +1965,12 @@ impl PyObject { #[cfg(test)] #[cfg_attr(not(feature = "gil-refs"), allow(deprecated))] mod tests { + use std::intrinsics::assert_inhabited; + use super::{Bound, Py, PyObject}; use crate::types::any::PyAnyMethods; - use crate::types::PyCapsule; use crate::types::{dict::IntoPyDict, PyDict, PyString}; + use crate::types::{PyCapsule, PyStringMethods}; use crate::{ffi, Borrowed, PyAny, PyNativeType, PyResult, Python, ToPyObject}; #[test] @@ -2161,6 +2170,20 @@ a = A() }); } + #[test] + fn test_bound_py_conversions() { + Python::with_gil(|py| { + let obj: Bound<'_, PyString> = PyString::new_bound(py, "hello world"); + let obj_unbound: &Py = obj.as_unbound(); + let obj_unbound_rebound: &Bound<'_, PyString> = obj_unbound.bind(py); + + let obj_unbound: Py = obj.unbind(); + let obj_bound: Bound<'_, PyString> = obj_unbound.into_bound(py); + + assert_eq!(obj.to_str().unwrap(), "hello world"); + }); + } + #[test] fn bound_from_borrowed_ptr_constructors() { // More detailed tests of the underlying semantics in pycell.rs