Skip to content

Commit

Permalink
Add as_bound conversion from gil-refs to Bound<T>
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Dec 23, 2023
1 parent e99058a commit eb20e82
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 207 deletions.
1 change: 1 addition & 0 deletions newsfragments/3691.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `PyNativeType::as_bound` to convert "GIL refs" to the new `Bound` smart pointer.
1 change: 1 addition & 0 deletions newsfragments/3691.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Include `PyNativeType` in `pyo3::prelude`.
4 changes: 2 additions & 2 deletions src/err/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
exceptions::{self, PyBaseException},
ffi,
};
use crate::{IntoPy, Py, PyAny, PyObject, Python, ToPyObject};
use crate::{IntoPy, Py, PyAny, PyNativeType, PyObject, Python, ToPyObject};
use std::borrow::Cow;
use std::cell::UnsafeCell;
use std::ffi::CString;
Expand Down Expand Up @@ -811,7 +811,7 @@ impl<'a> std::error::Error for PyDowncastError<'a> {}

impl<'a> std::fmt::Display for PyDowncastError<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
display_downcast_error(f, Bound::borrowed_from_gil_ref(&self.from), &self.to)
display_downcast_error(f, self.from.as_bound(), &self.to)
}
}

Expand Down
29 changes: 13 additions & 16 deletions src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ pub unsafe trait PyNativeType: Sized {
/// The form of this which is stored inside a `Py<T>` smart pointer.
type AsRefSource: HasPyGilRef<AsRefTarget = Self>;

/// Cast `&self` to a `Bound` smart pointer.
///
/// This is available as a migration tool to adjust code from the deprecated "GIL Refs"
/// API to the `Bound` smart pointer API.
fn as_bound<'a, 'py>(self: &'a &'py Self) -> &'a Bound<'py, Self::AsRefSource> {
// Safety: &'py Self is expected to be a Python pointer,
// so &'a &'py Self has the same layout as &'a Bound<'py, T>
unsafe { std::mem::transmute(self) }
}

/// Returns a GIL marker constrained to the lifetime of this type.
#[inline]
fn py(&self) -> Python<'_> {
Expand Down Expand Up @@ -172,18 +182,6 @@ impl<'py, T> Bound<'py, T> {
self.into_non_null().as_ptr()
}

/// Internal helper to convert e.g. &'a &'py PyDict to &'a Bound<'py, PyDict> for
/// backwards-compatibility during migration to removal of pool.
#[doc(hidden)] // public and doc(hidden) to use in examples and tests for now
pub fn borrowed_from_gil_ref<'a, U>(gil_ref: &'a &'py U) -> &'a Self
where
U: PyNativeType<AsRefSource = T>,
{
// Safety: &'py T::AsRefTarget is expected to be a Python pointer,
// so &'a &'py T::AsRefTarget has the same layout as &'a Bound<'py, T>
unsafe { std::mem::transmute(gil_ref) }
}

/// Internal helper to get to pool references for backwards compatibility
#[doc(hidden)] // public and doc(hidden) to use in examples and tests for now
pub fn as_gil_ref(&'py self) -> &'py T::AsRefTarget
Expand Down Expand Up @@ -1351,7 +1349,7 @@ where
{
/// Extracts `Self` from the source `PyObject`.
fn extract(ob: &'a PyAny) -> PyResult<Self> {
Bound::borrowed_from_gil_ref(&ob)
ob.as_bound()
.downcast()
.map(Clone::clone)
.map_err(Into::into)
Expand Down Expand Up @@ -1470,7 +1468,7 @@ impl PyObject {
mod tests {
use super::{Bound, Py, PyObject};
use crate::types::{PyDict, PyString};
use crate::{PyAny, PyResult, Python, ToPyObject};
use crate::{PyAny, PyNativeType, PyResult, Python, ToPyObject};

#[test]
fn test_call0() {
Expand Down Expand Up @@ -1597,8 +1595,7 @@ a = A()
#[test]
fn test_py2_into_py_object() {
Python::with_gil(|py| {
let instance: Bound<'_, PyAny> =
Bound::borrowed_from_gil_ref(&py.eval("object()", None, None).unwrap()).clone();
let instance = py.eval("object()", None, None).unwrap().as_bound().clone();
let ptr = instance.as_ptr();
let instance: PyObject = instance.clone().into();
assert_eq!(instance.as_ptr(), ptr);
Expand Down
1 change: 1 addition & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub use crate::marker::Python;
pub use crate::pycell::{PyCell, PyRef, PyRefMut};
pub use crate::pyclass_init::PyClassInitializer;
pub use crate::types::{PyAny, PyModule};
pub use crate::PyNativeType;

#[cfg(feature = "macros")]
pub use pyo3_macros::{pyclass, pyfunction, pymethods, pymodule, FromPyObject};
Expand Down
Loading

0 comments on commit eb20e82

Please sign in to comment.