diff --git a/src/instance.rs b/src/instance.rs index e857efc9..e3f3743e 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -206,6 +206,14 @@ impl<'py, T> Bound<'py, T> { ) } + /// Removes the connection for this `Bound` from the GIL, allowing + /// it to cross thread boundaries. + pub fn unbind(self) -> Py { + // Safety: the type T is known to be correct and the ownership of the + // pointer is transferred to the new Py instance. + unsafe { Py::from_non_null(self.into_non_null()) } + } + /// Casts this `Bound` as the corresponding "GIL Ref" type. /// /// This is a helper to be used for migration from the deprecated "GIL Refs" API. @@ -973,7 +981,7 @@ impl Py { where N: IntoPy>, { - self.bind(py).as_any().getattr(attr_name).map(Into::into) + self.bind(py).as_any().getattr(attr_name).map(Bound::unbind) } /// Sets an attribute value. @@ -1017,21 +1025,21 @@ impl Py { args: impl IntoPy>, kwargs: Option<&PyDict>, ) -> PyResult { - self.bind(py).as_any().call(args, kwargs).map(Into::into) + self.bind(py).as_any().call(args, kwargs).map(Bound::unbind) } /// Calls the object with only positional arguments. /// /// This is equivalent to the Python expression `self(*args)`. pub fn call1(&self, py: Python<'_>, args: impl IntoPy>) -> PyResult { - self.bind(py).as_any().call1(args).map(Into::into) + self.bind(py).as_any().call1(args).map(Bound::unbind) } /// Calls the object without arguments. /// /// This is equivalent to the Python expression `self()`. pub fn call0(&self, py: Python<'_>) -> PyResult { - self.bind(py).as_any().call0().map(Into::into) + self.bind(py).as_any().call0().map(Bound::unbind) } /// Calls a method on the object. @@ -1054,7 +1062,7 @@ impl Py { self.bind(py) .as_any() .call_method(name, args, kwargs) - .map(Into::into) + .map(Bound::unbind) } /// Calls a method on the object with only positional arguments. @@ -1071,7 +1079,7 @@ impl Py { self.bind(py) .as_any() .call_method1(name, args) - .map(Into::into) + .map(Bound::unbind) } /// Calls a method on the object with no arguments. @@ -1084,7 +1092,7 @@ impl Py { where N: IntoPy>, { - self.bind(py).as_any().call_method0(name).map(Into::into) + self.bind(py).as_any().call_method0(name).map(Bound::unbind) } /// Create a `Py` instance by taking ownership of the given FFI pointer. @@ -1292,7 +1300,7 @@ where impl std::convert::From> for Py { #[inline] fn from(other: Bound<'_, T>) -> Self { - unsafe { Self::from_non_null(other.into_non_null()) } + other.unbind() } } @@ -1618,7 +1626,7 @@ a = A() .as_borrowed() .to_owned(); let ptr = instance.as_ptr(); - let instance: PyObject = instance.clone().into(); + let instance: PyObject = instance.clone().unbind(); assert_eq!(instance.as_ptr(), ptr); }) } diff --git a/src/types/set.rs b/src/types/set.rs index a1ffaa3e..be65500b 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -94,7 +94,7 @@ impl PySet { /// Removes and returns an arbitrary element from the set. pub fn pop(&self) -> Option { - self.as_borrowed().pop().map(Py::from) + self.as_borrowed().pop().map(Bound::unbind) } /// Returns an iterator of values in this set. diff --git a/src/types/string.rs b/src/types/string.rs index 65f5a392..0ee64be5 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -435,13 +435,13 @@ impl Py { impl IntoPy> for Bound<'_, PyString> { fn into_py(self, _py: Python<'_>) -> Py { - self.into() + self.unbind() } } impl IntoPy> for &Bound<'_, PyString> { fn into_py(self, _py: Python<'_>) -> Py { - self.clone().into() + self.clone().unbind() } }