Skip to content

Commit

Permalink
Add .as_borrowed() conversion from gil-refs to Bound<T>
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Dec 26, 2023
1 parent f37c682 commit e9dd521
Show file tree
Hide file tree
Showing 20 changed files with 185 additions and 231 deletions.
1 change: 1 addition & 0 deletions newsfragments/3692.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/3692.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Include `PyNativeType` in `pyo3::prelude`.
7 changes: 4 additions & 3 deletions src/conversions/chrono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
//! }
//! ```
use crate::exceptions::{PyTypeError, PyUserWarning, PyValueError};
use crate::instance::Bound;
#[cfg(Py_LIMITED_API)]
use crate::sync::GILOnceCell;
#[cfg(not(Py_LIMITED_API))]
Expand All @@ -56,7 +55,9 @@ use crate::types::{
};
#[cfg(Py_LIMITED_API)]
use crate::{intern, PyDowncastError};
use crate::{FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject};
use crate::{
FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject, PyResult, Python, ToPyObject,
};
use chrono::offset::{FixedOffset, Utc};
use chrono::{
DateTime, Datelike, Duration, NaiveDate, NaiveDateTime, NaiveTime, Offset, TimeZone, Timelike,
Expand Down Expand Up @@ -466,7 +467,7 @@ fn warn_truncated_leap_second(obj: &PyAny) {
"ignored leap-second, `datetime` does not support leap-seconds",
0,
) {
e.write_unraisable_bound(py, Some(Bound::borrowed_from_gil_ref(&obj)))
e.write_unraisable_bound(py, Some(&obj.as_borrowed()))
};
}

Expand Down
6 changes: 3 additions & 3 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 @@ -542,7 +542,7 @@ impl PyErr {
)]
#[inline]
pub fn write_unraisable(self, py: Python<'_>, obj: Option<&PyAny>) {
self.write_unraisable_bound(py, obj.as_ref().map(Bound::borrowed_from_gil_ref))
self.write_unraisable_bound(py, obj.map(PyAny::as_borrowed).as_deref())
}

/// Reports the error as unraisable.
Expand Down Expand Up @@ -821,7 +821,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_borrowed(), &self.to)
}
}

Expand Down
42 changes: 20 additions & 22 deletions src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ 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 `Borrowed` smart pointer.
///
/// `Borrowed<T>` implements `Deref<Target=Bound<T>>`, so can also be used in locations
/// where `Bound<T>` is expected.
///
/// This is available as a migration tool to adjust code from the deprecated "GIL Refs"
/// API to the `Bound` smart pointer API.
fn as_borrowed<'py>(&'py self) -> Borrowed<'py, 'py, Self::AsRefSource> {
// Safety: &'py Self is expected to be a Python pointer,
// so has the same layout as Borrowed<'py, '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 @@ -184,18 +197,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) }
}

/// Casts this `Bound<T>` as the corresponding "GIL Ref" type.
///
/// This is a helper to be used for migration from the deprecated "GIL Refs" API.
Expand Down Expand Up @@ -311,12 +312,6 @@ impl<'py, T> Borrowed<'py, 'py, T>
where
T: HasPyGilRef,
{
pub(crate) fn from_gil_ref(gil_ref: &'py T::AsRefTarget) -> Self {
// Safety: &'py T::AsRefTarget is expected to be a Python pointer,
// so &'py T::AsRefTarget has the same layout as Self.
unsafe { std::mem::transmute(gil_ref) }
}

// pub(crate) fn into_gil_ref(self) -> &'py T::AsRefTarget {
// // Safety: self is a borrow over `'py`.
// unsafe { self.py().from_borrowed_ptr(self.0.as_ptr()) }
Expand Down Expand Up @@ -1366,7 +1361,7 @@ where
{
/// Extracts `Self` from the source `PyObject`.
fn extract(ob: &'a PyAny) -> PyResult<Self> {
Bound::borrowed_from_gil_ref(&ob)
ob.as_borrowed()
.downcast()
.map(Clone::clone)
.map_err(Into::into)
Expand Down Expand Up @@ -1485,7 +1480,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 @@ -1612,8 +1607,11 @@ 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_borrowed()
.to_owned();
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 e9dd521

Please sign in to comment.