Merge pull request #3692 from davidhewitt/as-bound

Add `as_borrowed` conversion from gil-refs to `Bound<T>`
This commit is contained in:
Adam Reichold 2023-12-26 10:45:43 +00:00 committed by GitHub
commit c44d2f53d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 201 additions and 242 deletions

View file

@ -0,0 +1 @@
Add `PyNativeType::as_bound` to convert "GIL refs" to the new `Bound` smart pointer.

View file

@ -0,0 +1 @@
Include `PyNativeType` in `pyo3::prelude`.

View file

@ -42,7 +42,6 @@
//! } //! }
//! ``` //! ```
use crate::exceptions::{PyTypeError, PyUserWarning, PyValueError}; use crate::exceptions::{PyTypeError, PyUserWarning, PyValueError};
use crate::instance::Bound;
#[cfg(Py_LIMITED_API)] #[cfg(Py_LIMITED_API)]
use crate::sync::GILOnceCell; use crate::sync::GILOnceCell;
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
@ -56,7 +55,9 @@ use crate::types::{
}; };
#[cfg(Py_LIMITED_API)] #[cfg(Py_LIMITED_API)]
use crate::{intern, PyDowncastError}; 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::offset::{FixedOffset, Utc};
use chrono::{ use chrono::{
DateTime, Datelike, Duration, NaiveDate, NaiveDateTime, NaiveTime, Offset, TimeZone, Timelike, DateTime, Datelike, Duration, NaiveDate, NaiveDateTime, NaiveTime, Offset, TimeZone, Timelike,
@ -466,7 +467,7 @@ fn warn_truncated_leap_second(obj: &PyAny) {
"ignored leap-second, `datetime` does not support leap-seconds", "ignored leap-second, `datetime` does not support leap-seconds",
0, 0,
) { ) {
e.write_unraisable_bound(py, Some(Bound::borrowed_from_gil_ref(&obj))) e.write_unraisable_bound(py, Some(&obj.as_borrowed()))
}; };
} }

View file

@ -7,7 +7,7 @@ use crate::{
exceptions::{self, PyBaseException}, exceptions::{self, PyBaseException},
ffi, ffi,
}; };
use crate::{IntoPy, Py, PyAny, PyObject, Python, ToPyObject}; use crate::{IntoPy, Py, PyAny, PyNativeType, PyObject, Python, ToPyObject};
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use std::ffi::CString; use std::ffi::CString;
@ -542,7 +542,7 @@ impl PyErr {
)] )]
#[inline] #[inline]
pub fn write_unraisable(self, py: Python<'_>, obj: Option<&PyAny>) { 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. /// Reports the error as unraisable.
@ -821,7 +821,7 @@ impl<'a> std::error::Error for PyDowncastError<'a> {}
impl<'a> std::fmt::Display for PyDowncastError<'a> { impl<'a> std::fmt::Display for PyDowncastError<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { 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)
} }
} }

View file

@ -28,6 +28,19 @@ pub unsafe trait PyNativeType: Sized {
/// The form of this which is stored inside a `Py<T>` smart pointer. /// The form of this which is stored inside a `Py<T>` smart pointer.
type AsRefSource: HasPyGilRef<AsRefTarget = Self>; 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(&self) -> Borrowed<'_, '_, 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. /// Returns a GIL marker constrained to the lifetime of this type.
#[inline] #[inline]
fn py(&self) -> Python<'_> { fn py(&self) -> Python<'_> {
@ -184,16 +197,13 @@ impl<'py, T> Bound<'py, T> {
self.into_non_null().as_ptr() self.into_non_null().as_ptr()
} }
/// Internal helper to convert e.g. &'a &'py PyDict to &'a Bound<'py, PyDict> for /// Casts this `Bound<T>` to a `Borrowed<T>` smart pointer.
/// backwards-compatibility during migration to removal of pool. pub fn as_borrowed<'a>(&'a self) -> Borrowed<'a, 'py, T> {
#[doc(hidden)] // public and doc(hidden) to use in examples and tests for now Borrowed(
pub fn borrowed_from_gil_ref<'a, U>(gil_ref: &'a &'py U) -> &'a Self unsafe { NonNull::new_unchecked(self.as_ptr()) },
where PhantomData,
U: PyNativeType<AsRefSource = T>, self.py(),
{ )
// 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. /// Casts this `Bound<T>` as the corresponding "GIL Ref" type.
@ -299,11 +309,7 @@ impl<'a, 'py> Borrowed<'a, 'py, PyAny> {
impl<'a, 'py, T> From<&'a Bound<'py, T>> for Borrowed<'a, 'py, T> { impl<'a, 'py, T> From<&'a Bound<'py, T>> for Borrowed<'a, 'py, T> {
/// Create borrow on a Bound /// Create borrow on a Bound
fn from(instance: &'a Bound<'py, T>) -> Self { fn from(instance: &'a Bound<'py, T>) -> Self {
Self( instance.as_borrowed()
unsafe { NonNull::new_unchecked(instance.as_ptr()) },
PhantomData,
instance.py(),
)
} }
} }
@ -311,12 +317,6 @@ impl<'py, T> Borrowed<'py, 'py, T>
where where
T: HasPyGilRef, 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 { // pub(crate) fn into_gil_ref(self) -> &'py T::AsRefTarget {
// // Safety: self is a borrow over `'py`. // // Safety: self is a borrow over `'py`.
// unsafe { self.py().from_borrowed_ptr(self.0.as_ptr()) } // unsafe { self.py().from_borrowed_ptr(self.0.as_ptr()) }
@ -1366,7 +1366,7 @@ where
{ {
/// Extracts `Self` from the source `PyObject`. /// Extracts `Self` from the source `PyObject`.
fn extract(ob: &'a PyAny) -> PyResult<Self> { fn extract(ob: &'a PyAny) -> PyResult<Self> {
Bound::borrowed_from_gil_ref(&ob) ob.as_borrowed()
.downcast() .downcast()
.map(Clone::clone) .map(Clone::clone)
.map_err(Into::into) .map_err(Into::into)
@ -1485,7 +1485,7 @@ impl PyObject {
mod tests { mod tests {
use super::{Bound, Py, PyObject}; use super::{Bound, Py, PyObject};
use crate::types::{PyDict, PyString}; use crate::types::{PyDict, PyString};
use crate::{PyAny, PyResult, Python, ToPyObject}; use crate::{PyAny, PyNativeType, PyResult, Python, ToPyObject};
#[test] #[test]
fn test_call0() { fn test_call0() {
@ -1612,8 +1612,11 @@ a = A()
#[test] #[test]
fn test_py2_into_py_object() { fn test_py2_into_py_object() {
Python::with_gil(|py| { Python::with_gil(|py| {
let instance: Bound<'_, PyAny> = let instance = py
Bound::borrowed_from_gil_ref(&py.eval("object()", None, None).unwrap()).clone(); .eval("object()", None, None)
.unwrap()
.as_borrowed()
.to_owned();
let ptr = instance.as_ptr(); let ptr = instance.as_ptr();
let instance: PyObject = instance.clone().into(); let instance: PyObject = instance.clone().into();
assert_eq!(instance.as_ptr(), ptr); assert_eq!(instance.as_ptr(), ptr);

View file

@ -17,6 +17,7 @@ pub use crate::marker::Python;
pub use crate::pycell::{PyCell, PyRef, PyRefMut}; pub use crate::pycell::{PyCell, PyRef, PyRefMut};
pub use crate::pyclass_init::PyClassInitializer; pub use crate::pyclass_init::PyClassInitializer;
pub use crate::types::{PyAny, PyModule}; pub use crate::types::{PyAny, PyModule};
pub use crate::PyNativeType;
#[cfg(feature = "macros")] #[cfg(feature = "macros")]
pub use pyo3_macros::{pyclass, pyfunction, pymethods, pymodule, FromPyObject}; pub use pyo3_macros::{pyclass, pyfunction, pymethods, pymodule, FromPyObject};

View file

@ -73,7 +73,7 @@ impl PyAny {
/// This is equivalent to the Python expression `self is other`. /// This is equivalent to the Python expression `self is other`.
#[inline] #[inline]
pub fn is<T: AsPyPointer>(&self, other: &T) -> bool { pub fn is<T: AsPyPointer>(&self, other: &T) -> bool {
Bound::borrowed_from_gil_ref(&self).is(other) self.as_borrowed().is(other)
} }
/// Determines whether this object has the given attribute. /// Determines whether this object has the given attribute.
@ -102,7 +102,7 @@ impl PyAny {
where where
N: IntoPy<Py<PyString>>, N: IntoPy<Py<PyString>>,
{ {
Bound::borrowed_from_gil_ref(&self).hasattr(attr_name) self.as_borrowed().hasattr(attr_name)
} }
/// Retrieves an attribute value. /// Retrieves an attribute value.
@ -131,7 +131,7 @@ impl PyAny {
where where
N: IntoPy<Py<PyString>>, N: IntoPy<Py<PyString>>,
{ {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed()
.getattr(attr_name) .getattr(attr_name)
.map(Bound::into_gil_ref) .map(Bound::into_gil_ref)
} }
@ -208,7 +208,7 @@ impl PyAny {
N: IntoPy<Py<PyString>>, N: IntoPy<Py<PyString>>,
V: ToPyObject, V: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).setattr(attr_name, value) self.as_borrowed().setattr(attr_name, value)
} }
/// Deletes an attribute. /// Deletes an attribute.
@ -221,7 +221,7 @@ impl PyAny {
where where
N: IntoPy<Py<PyString>>, N: IntoPy<Py<PyString>>,
{ {
Bound::borrowed_from_gil_ref(&self).delattr(attr_name) self.as_borrowed().delattr(attr_name)
} }
/// Returns an [`Ordering`] between `self` and `other`. /// Returns an [`Ordering`] between `self` and `other`.
@ -274,7 +274,7 @@ impl PyAny {
where where
O: ToPyObject, O: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).compare(other) self.as_borrowed().compare(other)
} }
/// Tests whether two Python objects obey a given [`CompareOp`]. /// Tests whether two Python objects obey a given [`CompareOp`].
@ -315,7 +315,7 @@ impl PyAny {
where where
O: ToPyObject, O: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed()
.rich_compare(other, compare_op) .rich_compare(other, compare_op)
.map(Bound::into_gil_ref) .map(Bound::into_gil_ref)
} }
@ -327,7 +327,7 @@ impl PyAny {
where where
O: ToPyObject, O: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).lt(other) self.as_borrowed().lt(other)
} }
/// Tests whether this object is less than or equal to another. /// Tests whether this object is less than or equal to another.
@ -337,7 +337,7 @@ impl PyAny {
where where
O: ToPyObject, O: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).le(other) self.as_borrowed().le(other)
} }
/// Tests whether this object is equal to another. /// Tests whether this object is equal to another.
@ -347,7 +347,7 @@ impl PyAny {
where where
O: ToPyObject, O: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).eq(other) self.as_borrowed().eq(other)
} }
/// Tests whether this object is not equal to another. /// Tests whether this object is not equal to another.
@ -357,7 +357,7 @@ impl PyAny {
where where
O: ToPyObject, O: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).ne(other) self.as_borrowed().ne(other)
} }
/// Tests whether this object is greater than another. /// Tests whether this object is greater than another.
@ -367,7 +367,7 @@ impl PyAny {
where where
O: ToPyObject, O: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).gt(other) self.as_borrowed().gt(other)
} }
/// Tests whether this object is greater than or equal to another. /// Tests whether this object is greater than or equal to another.
@ -377,7 +377,7 @@ impl PyAny {
where where
O: ToPyObject, O: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).ge(other) self.as_borrowed().ge(other)
} }
/// Determines whether this object appears callable. /// Determines whether this object appears callable.
@ -408,7 +408,7 @@ impl PyAny {
/// ///
/// [1]: https://docs.python.org/3/library/functions.html#callable /// [1]: https://docs.python.org/3/library/functions.html#callable
pub fn is_callable(&self) -> bool { pub fn is_callable(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).is_callable() self.as_borrowed().is_callable()
} }
/// Calls the object. /// Calls the object.
@ -446,7 +446,7 @@ impl PyAny {
args: impl IntoPy<Py<PyTuple>>, args: impl IntoPy<Py<PyTuple>>,
kwargs: Option<&PyDict>, kwargs: Option<&PyDict>,
) -> PyResult<&PyAny> { ) -> PyResult<&PyAny> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed()
.call(args, kwargs) .call(args, kwargs)
.map(Bound::into_gil_ref) .map(Bound::into_gil_ref)
} }
@ -472,9 +472,7 @@ impl PyAny {
/// ///
/// This is equivalent to the Python expression `help()`. /// This is equivalent to the Python expression `help()`.
pub fn call0(&self) -> PyResult<&PyAny> { pub fn call0(&self) -> PyResult<&PyAny> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().call0().map(Bound::into_gil_ref)
.call0()
.map(Bound::into_gil_ref)
} }
/// Calls the object with only positional arguments. /// Calls the object with only positional arguments.
@ -505,9 +503,7 @@ impl PyAny {
/// # } /// # }
/// ``` /// ```
pub fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyAny> { pub fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyAny> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().call1(args).map(Bound::into_gil_ref)
.call1(args)
.map(Bound::into_gil_ref)
} }
/// Calls a method on the object. /// Calls a method on the object.
@ -550,7 +546,7 @@ impl PyAny {
N: IntoPy<Py<PyString>>, N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>, A: IntoPy<Py<PyTuple>>,
{ {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed()
.call_method(name, args, kwargs) .call_method(name, args, kwargs)
.map(Bound::into_gil_ref) .map(Bound::into_gil_ref)
} }
@ -590,7 +586,7 @@ impl PyAny {
where where
N: IntoPy<Py<PyString>>, N: IntoPy<Py<PyString>>,
{ {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed()
.call_method0(name) .call_method0(name)
.map(Bound::into_gil_ref) .map(Bound::into_gil_ref)
} }
@ -632,7 +628,7 @@ impl PyAny {
N: IntoPy<Py<PyString>>, N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>, A: IntoPy<Py<PyTuple>>,
{ {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed()
.call_method1(name, args) .call_method1(name, args)
.map(Bound::into_gil_ref) .map(Bound::into_gil_ref)
} }
@ -649,7 +645,7 @@ impl PyAny {
/// ///
/// This applies truth value testing equivalent to the Python expression `bool(self)`. /// This applies truth value testing equivalent to the Python expression `bool(self)`.
pub fn is_truthy(&self) -> PyResult<bool> { pub fn is_truthy(&self) -> PyResult<bool> {
Bound::borrowed_from_gil_ref(&self).is_truthy() self.as_borrowed().is_truthy()
} }
/// Returns whether the object is considered to be None. /// Returns whether the object is considered to be None.
@ -657,7 +653,7 @@ impl PyAny {
/// This is equivalent to the Python expression `self is None`. /// This is equivalent to the Python expression `self is None`.
#[inline] #[inline]
pub fn is_none(&self) -> bool { pub fn is_none(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).is_none() self.as_borrowed().is_none()
} }
/// Returns whether the object is Ellipsis, e.g. `...`. /// Returns whether the object is Ellipsis, e.g. `...`.
@ -665,14 +661,14 @@ impl PyAny {
/// This is equivalent to the Python expression `self is ...`. /// This is equivalent to the Python expression `self is ...`.
#[deprecated(since = "0.20.0", note = "use `.is(py.Ellipsis())` instead")] #[deprecated(since = "0.20.0", note = "use `.is(py.Ellipsis())` instead")]
pub fn is_ellipsis(&self) -> bool { pub fn is_ellipsis(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).is_ellipsis() self.as_borrowed().is_ellipsis()
} }
/// Returns true if the sequence or mapping has a length of 0. /// Returns true if the sequence or mapping has a length of 0.
/// ///
/// This is equivalent to the Python expression `len(self) == 0`. /// This is equivalent to the Python expression `len(self) == 0`.
pub fn is_empty(&self) -> PyResult<bool> { pub fn is_empty(&self) -> PyResult<bool> {
Bound::borrowed_from_gil_ref(&self).is_empty() self.as_borrowed().is_empty()
} }
/// Gets an item from the collection. /// Gets an item from the collection.
@ -682,9 +678,7 @@ impl PyAny {
where where
K: ToPyObject, K: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().get_item(key).map(Bound::into_gil_ref)
.get_item(key)
.map(Bound::into_gil_ref)
} }
/// Sets a collection item value. /// Sets a collection item value.
@ -695,7 +689,7 @@ impl PyAny {
K: ToPyObject, K: ToPyObject,
V: ToPyObject, V: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).set_item(key, value) self.as_borrowed().set_item(key, value)
} }
/// Deletes an item from the collection. /// Deletes an item from the collection.
@ -705,7 +699,7 @@ impl PyAny {
where where
K: ToPyObject, K: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).del_item(key) self.as_borrowed().del_item(key)
} }
/// Takes an object and returns an iterator for it. /// Takes an object and returns an iterator for it.
@ -713,20 +707,18 @@ impl PyAny {
/// This is typically a new iterator but if the argument is an iterator, /// This is typically a new iterator but if the argument is an iterator,
/// this returns itself. /// this returns itself.
pub fn iter(&self) -> PyResult<&PyIterator> { pub fn iter(&self) -> PyResult<&PyIterator> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().iter().map(Bound::into_gil_ref)
.iter()
.map(Bound::into_gil_ref)
} }
/// Returns the Python type object for this object's type. /// Returns the Python type object for this object's type.
pub fn get_type(&self) -> &PyType { pub fn get_type(&self) -> &PyType {
Bound::borrowed_from_gil_ref(&self).get_type() self.as_borrowed().get_type()
} }
/// Returns the Python type pointer for this object. /// Returns the Python type pointer for this object.
#[inline] #[inline]
pub fn get_type_ptr(&self) -> *mut ffi::PyTypeObject { pub fn get_type_ptr(&self) -> *mut ffi::PyTypeObject {
Bound::borrowed_from_gil_ref(&self).get_type_ptr() self.as_borrowed().get_type_ptr()
} }
/// Downcast this `PyAny` to a concrete Python type or pyclass. /// Downcast this `PyAny` to a concrete Python type or pyclass.
@ -863,46 +855,42 @@ impl PyAny {
/// Returns the reference count for the Python object. /// Returns the reference count for the Python object.
pub fn get_refcnt(&self) -> isize { pub fn get_refcnt(&self) -> isize {
Bound::borrowed_from_gil_ref(&self).get_refcnt() self.as_borrowed().get_refcnt()
} }
/// Computes the "repr" representation of self. /// Computes the "repr" representation of self.
/// ///
/// This is equivalent to the Python expression `repr(self)`. /// This is equivalent to the Python expression `repr(self)`.
pub fn repr(&self) -> PyResult<&PyString> { pub fn repr(&self) -> PyResult<&PyString> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().repr().map(Bound::into_gil_ref)
.repr()
.map(Bound::into_gil_ref)
} }
/// Computes the "str" representation of self. /// Computes the "str" representation of self.
/// ///
/// This is equivalent to the Python expression `str(self)`. /// This is equivalent to the Python expression `str(self)`.
pub fn str(&self) -> PyResult<&PyString> { pub fn str(&self) -> PyResult<&PyString> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().str().map(Bound::into_gil_ref)
.str()
.map(Bound::into_gil_ref)
} }
/// Retrieves the hash code of self. /// Retrieves the hash code of self.
/// ///
/// This is equivalent to the Python expression `hash(self)`. /// This is equivalent to the Python expression `hash(self)`.
pub fn hash(&self) -> PyResult<isize> { pub fn hash(&self) -> PyResult<isize> {
Bound::borrowed_from_gil_ref(&self).hash() self.as_borrowed().hash()
} }
/// Returns the length of the sequence or mapping. /// Returns the length of the sequence or mapping.
/// ///
/// This is equivalent to the Python expression `len(self)`. /// This is equivalent to the Python expression `len(self)`.
pub fn len(&self) -> PyResult<usize> { pub fn len(&self) -> PyResult<usize> {
Bound::borrowed_from_gil_ref(&self).len() self.as_borrowed().len()
} }
/// Returns the list of attributes of this object. /// Returns the list of attributes of this object.
/// ///
/// This is equivalent to the Python expression `dir(self)`. /// This is equivalent to the Python expression `dir(self)`.
pub fn dir(&self) -> &PyList { pub fn dir(&self) -> &PyList {
Bound::borrowed_from_gil_ref(&self).dir().into_gil_ref() self.as_borrowed().dir().into_gil_ref()
} }
/// Checks whether this object is an instance of type `ty`. /// Checks whether this object is an instance of type `ty`.
@ -910,7 +898,7 @@ impl PyAny {
/// This is equivalent to the Python expression `isinstance(self, ty)`. /// This is equivalent to the Python expression `isinstance(self, ty)`.
#[inline] #[inline]
pub fn is_instance(&self, ty: &PyAny) -> PyResult<bool> { pub fn is_instance(&self, ty: &PyAny) -> PyResult<bool> {
Bound::borrowed_from_gil_ref(&self).is_instance(Bound::borrowed_from_gil_ref(&ty)) self.as_borrowed().is_instance(&ty.as_borrowed())
} }
/// Checks whether this object is an instance of exactly type `ty` (not a subclass). /// Checks whether this object is an instance of exactly type `ty` (not a subclass).
@ -918,7 +906,7 @@ impl PyAny {
/// This is equivalent to the Python expression `type(self) is ty`. /// This is equivalent to the Python expression `type(self) is ty`.
#[inline] #[inline]
pub fn is_exact_instance(&self, ty: &PyAny) -> bool { pub fn is_exact_instance(&self, ty: &PyAny) -> bool {
Bound::borrowed_from_gil_ref(&self).is_exact_instance(Bound::borrowed_from_gil_ref(&ty)) self.as_borrowed().is_exact_instance(&ty.as_borrowed())
} }
/// Checks whether this object is an instance of type `T`. /// Checks whether this object is an instance of type `T`.
@ -927,7 +915,7 @@ impl PyAny {
/// if the type `T` is known at compile time. /// if the type `T` is known at compile time.
#[inline] #[inline]
pub fn is_instance_of<T: PyTypeInfo>(&self) -> bool { pub fn is_instance_of<T: PyTypeInfo>(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).is_instance_of::<T>() self.as_borrowed().is_instance_of::<T>()
} }
/// Checks whether this object is an instance of exactly type `T`. /// Checks whether this object is an instance of exactly type `T`.
@ -936,7 +924,7 @@ impl PyAny {
/// if the type `T` is known at compile time. /// if the type `T` is known at compile time.
#[inline] #[inline]
pub fn is_exact_instance_of<T: PyTypeInfo>(&self) -> bool { pub fn is_exact_instance_of<T: PyTypeInfo>(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).is_exact_instance_of::<T>() self.as_borrowed().is_exact_instance_of::<T>()
} }
/// Determines if self contains `value`. /// Determines if self contains `value`.
@ -946,7 +934,7 @@ impl PyAny {
where where
V: ToPyObject, V: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).contains(value) self.as_borrowed().contains(value)
} }
/// Returns a GIL marker constrained to the lifetime of this type. /// Returns a GIL marker constrained to the lifetime of this type.
@ -985,9 +973,7 @@ impl PyAny {
/// This is equivalent to the Python expression `super()` /// This is equivalent to the Python expression `super()`
#[cfg(not(PyPy))] #[cfg(not(PyPy))]
pub fn py_super(&self) -> PyResult<&PySuper> { pub fn py_super(&self) -> PyResult<&PySuper> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().py_super().map(Bound::into_gil_ref)
.py_super()
.map(Bound::into_gil_ref)
} }
} }
@ -2193,7 +2179,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
#[cfg(not(PyPy))] #[cfg(not(PyPy))]
fn py_super(&self) -> PyResult<Bound<'py, PySuper>> { fn py_super(&self) -> PyResult<Bound<'py, PySuper>> {
PySuper::new_bound(Bound::borrowed_from_gil_ref(&self.get_type()), self) PySuper::new_bound(&self.get_type().as_borrowed(), self)
} }
} }

View file

@ -1,8 +1,8 @@
#[cfg(feature = "experimental-inspect")] #[cfg(feature = "experimental-inspect")]
use crate::inspect::types::TypeInfo; use crate::inspect::types::TypeInfo;
use crate::{ use crate::{
exceptions::PyTypeError, ffi, instance::Bound, FromPyObject, IntoPy, PyAny, PyObject, PyResult, exceptions::PyTypeError, ffi, instance::Bound, FromPyObject, IntoPy, PyAny, PyNativeType,
Python, ToPyObject, PyObject, PyResult, Python, ToPyObject,
}; };
/// Represents a Python `bool`. /// Represents a Python `bool`.
@ -21,7 +21,7 @@ impl PyBool {
/// Gets whether this boolean is `true`. /// Gets whether this boolean is `true`.
#[inline] #[inline]
pub fn is_true(&self) -> bool { pub fn is_true(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).is_true() self.as_borrowed().is_true()
} }
} }

View file

@ -1,6 +1,6 @@
use crate::err::{PyErr, PyResult}; use crate::err::{PyErr, PyResult};
use crate::instance::{Borrowed, Bound}; use crate::instance::{Borrowed, Bound};
use crate::{ffi, AsPyPointer, Py, PyAny, Python}; use crate::{ffi, AsPyPointer, Py, PyAny, PyNativeType, Python};
use std::os::raw::c_char; use std::os::raw::c_char;
use std::slice; use std::slice;
@ -75,12 +75,12 @@ impl PyByteArray {
/// Gets the length of the bytearray. /// Gets the length of the bytearray.
#[inline] #[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
Bound::borrowed_from_gil_ref(&self).len() self.as_borrowed().len()
} }
/// Checks if the bytearray is empty. /// Checks if the bytearray is empty.
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).is_empty() self.as_borrowed().is_empty()
} }
/// Gets the start of the buffer containing the contents of the bytearray. /// Gets the start of the buffer containing the contents of the bytearray.
@ -89,7 +89,7 @@ impl PyByteArray {
/// ///
/// See the safety requirements of [`PyByteArray::as_bytes`] and [`PyByteArray::as_bytes_mut`]. /// See the safety requirements of [`PyByteArray::as_bytes`] and [`PyByteArray::as_bytes_mut`].
pub fn data(&self) -> *mut u8 { pub fn data(&self) -> *mut u8 {
Bound::borrowed_from_gil_ref(&self).data() self.as_borrowed().data()
} }
/// Extracts a slice of the `ByteArray`'s entire buffer. /// Extracts a slice of the `ByteArray`'s entire buffer.
@ -188,7 +188,7 @@ impl PyByteArray {
/// } /// }
/// ``` /// ```
pub unsafe fn as_bytes(&self) -> &[u8] { pub unsafe fn as_bytes(&self) -> &[u8] {
Borrowed::from_gil_ref(self).as_bytes() self.as_borrowed().as_bytes()
} }
/// Extracts a mutable slice of the `ByteArray`'s entire buffer. /// Extracts a mutable slice of the `ByteArray`'s entire buffer.
@ -200,7 +200,7 @@ impl PyByteArray {
/// apply to this function as well. /// apply to this function as well.
#[allow(clippy::mut_from_ref)] #[allow(clippy::mut_from_ref)]
pub unsafe fn as_bytes_mut(&self) -> &mut [u8] { pub unsafe fn as_bytes_mut(&self) -> &mut [u8] {
Borrowed::from_gil_ref(self).as_bytes_mut() self.as_borrowed().as_bytes_mut()
} }
/// Copies the contents of the bytearray to a Rust vector. /// Copies the contents of the bytearray to a Rust vector.
@ -222,7 +222,7 @@ impl PyByteArray {
/// # }); /// # });
/// ``` /// ```
pub fn to_vec(&self) -> Vec<u8> { pub fn to_vec(&self) -> Vec<u8> {
Bound::borrowed_from_gil_ref(&self).to_vec() self.as_borrowed().to_vec()
} }
/// Resizes the bytearray object to the new length `len`. /// Resizes the bytearray object to the new length `len`.
@ -230,7 +230,7 @@ impl PyByteArray {
/// Note that this will invalidate any pointers obtained by [PyByteArray::data], as well as /// Note that this will invalidate any pointers obtained by [PyByteArray::data], as well as
/// any (unsafe) slices obtained from [PyByteArray::as_bytes] and [PyByteArray::as_bytes_mut]. /// any (unsafe) slices obtained from [PyByteArray::as_bytes] and [PyByteArray::as_bytes_mut].
pub fn resize(&self, len: usize) -> PyResult<()> { pub fn resize(&self, len: usize) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).resize(len) self.as_borrowed().resize(len)
} }
} }
@ -400,16 +400,16 @@ impl<'py> PyByteArrayMethods<'py> for Bound<'py, PyByteArray> {
} }
fn data(&self) -> *mut u8 { fn data(&self) -> *mut u8 {
Borrowed::from(self).data() self.as_borrowed().data()
} }
unsafe fn as_bytes(&self) -> &[u8] { unsafe fn as_bytes(&self) -> &[u8] {
Borrowed::from(self).as_bytes() self.as_borrowed().as_bytes()
} }
#[allow(clippy::mut_from_ref)] #[allow(clippy::mut_from_ref)]
unsafe fn as_bytes_mut(&self) -> &mut [u8] { unsafe fn as_bytes_mut(&self) -> &mut [u8] {
Borrowed::from(self).as_bytes_mut() self.as_borrowed().as_bytes_mut()
} }
fn to_vec(&self) -> Vec<u8> { fn to_vec(&self) -> Vec<u8> {

View file

@ -1,5 +1,5 @@
use crate::instance::{Borrowed, Bound}; use crate::instance::{Borrowed, Bound};
use crate::{ffi, FromPyObject, IntoPy, Py, PyAny, PyResult, Python, ToPyObject}; use crate::{ffi, FromPyObject, IntoPy, Py, PyAny, PyNativeType, PyResult, Python, ToPyObject};
use std::borrow::Cow; use std::borrow::Cow;
use std::ops::Index; use std::ops::Index;
use std::os::raw::c_char; use std::os::raw::c_char;
@ -89,7 +89,7 @@ impl PyBytes {
/// Gets the Python string as a byte slice. /// Gets the Python string as a byte slice.
#[inline] #[inline]
pub fn as_bytes(&self) -> &[u8] { pub fn as_bytes(&self) -> &[u8] {
Borrowed::from_gil_ref(self).as_bytes() self.as_borrowed().as_bytes()
} }
} }
@ -107,7 +107,7 @@ pub trait PyBytesMethods<'py> {
impl<'py> PyBytesMethods<'py> for Bound<'py, PyBytes> { impl<'py> PyBytesMethods<'py> for Bound<'py, PyBytes> {
#[inline] #[inline]
fn as_bytes(&self) -> &[u8] { fn as_bytes(&self) -> &[u8] {
Borrowed::from(self).as_bytes() self.as_borrowed().as_bytes()
} }
} }

View file

@ -223,15 +223,15 @@ impl PyDate {
impl PyDateAccess for PyDate { impl PyDateAccess for PyDate {
fn get_year(&self) -> i32 { fn get_year(&self) -> i32 {
Bound::borrowed_from_gil_ref(&self).get_year() self.as_borrowed().get_year()
} }
fn get_month(&self) -> u8 { fn get_month(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_month() self.as_borrowed().get_month()
} }
fn get_day(&self) -> u8 { fn get_day(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_day() self.as_borrowed().get_day()
} }
} }
@ -351,15 +351,15 @@ impl PyDateTime {
impl PyDateAccess for PyDateTime { impl PyDateAccess for PyDateTime {
fn get_year(&self) -> i32 { fn get_year(&self) -> i32 {
Bound::borrowed_from_gil_ref(&self).get_year() self.as_borrowed().get_year()
} }
fn get_month(&self) -> u8 { fn get_month(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_month() self.as_borrowed().get_month()
} }
fn get_day(&self) -> u8 { fn get_day(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_day() self.as_borrowed().get_day()
} }
} }
@ -379,23 +379,23 @@ impl PyDateAccess for Bound<'_, PyDateTime> {
impl PyTimeAccess for PyDateTime { impl PyTimeAccess for PyDateTime {
fn get_hour(&self) -> u8 { fn get_hour(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_hour() self.as_borrowed().get_hour()
} }
fn get_minute(&self) -> u8 { fn get_minute(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_minute() self.as_borrowed().get_minute()
} }
fn get_second(&self) -> u8 { fn get_second(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_second() self.as_borrowed().get_second()
} }
fn get_microsecond(&self) -> u32 { fn get_microsecond(&self) -> u32 {
Bound::borrowed_from_gil_ref(&self).get_microsecond() self.as_borrowed().get_microsecond()
} }
fn get_fold(&self) -> bool { fn get_fold(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).get_fold() self.as_borrowed().get_fold()
} }
} }
@ -423,7 +423,7 @@ impl PyTimeAccess for Bound<'_, PyDateTime> {
impl<'py> PyTzInfoAccess<'py> for &'py PyDateTime { impl<'py> PyTzInfoAccess<'py> for &'py PyDateTime {
fn get_tzinfo_bound(&self) -> Option<Bound<'py, PyTzInfo>> { fn get_tzinfo_bound(&self) -> Option<Bound<'py, PyTzInfo>> {
Bound::borrowed_from_gil_ref(self).get_tzinfo_bound() self.as_borrowed().get_tzinfo_bound()
} }
} }
@ -509,23 +509,23 @@ impl PyTime {
impl PyTimeAccess for PyTime { impl PyTimeAccess for PyTime {
fn get_hour(&self) -> u8 { fn get_hour(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_hour() self.as_borrowed().get_hour()
} }
fn get_minute(&self) -> u8 { fn get_minute(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_minute() self.as_borrowed().get_minute()
} }
fn get_second(&self) -> u8 { fn get_second(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_second() self.as_borrowed().get_second()
} }
fn get_microsecond(&self) -> u32 { fn get_microsecond(&self) -> u32 {
Bound::borrowed_from_gil_ref(&self).get_microsecond() self.as_borrowed().get_microsecond()
} }
fn get_fold(&self) -> bool { fn get_fold(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).get_fold() self.as_borrowed().get_fold()
} }
} }
@ -553,7 +553,7 @@ impl PyTimeAccess for Bound<'_, PyTime> {
impl<'py> PyTzInfoAccess<'py> for &'py PyTime { impl<'py> PyTzInfoAccess<'py> for &'py PyTime {
fn get_tzinfo_bound(&self) -> Option<Bound<'py, PyTzInfo>> { fn get_tzinfo_bound(&self) -> Option<Bound<'py, PyTzInfo>> {
Bound::borrowed_from_gil_ref(self).get_tzinfo_bound() self.as_borrowed().get_tzinfo_bound()
} }
} }
@ -644,15 +644,15 @@ impl PyDelta {
impl PyDeltaAccess for PyDelta { impl PyDeltaAccess for PyDelta {
fn get_days(&self) -> i32 { fn get_days(&self) -> i32 {
Bound::borrowed_from_gil_ref(&self).get_days() self.as_borrowed().get_days()
} }
fn get_seconds(&self) -> i32 { fn get_seconds(&self) -> i32 {
Bound::borrowed_from_gil_ref(&self).get_seconds() self.as_borrowed().get_seconds()
} }
fn get_microseconds(&self) -> i32 { fn get_microseconds(&self) -> i32 {
Bound::borrowed_from_gil_ref(&self).get_microseconds() self.as_borrowed().get_microseconds()
} }
} }

View file

@ -6,7 +6,7 @@ use crate::instance::{Borrowed, Bound};
use crate::py_result_ext::PyResultExt; use crate::py_result_ext::PyResultExt;
use crate::types::any::PyAnyMethods; use crate::types::any::PyAnyMethods;
use crate::types::{PyAny, PyList}; use crate::types::{PyAny, PyList};
use crate::{ffi, Python, ToPyObject}; use crate::{ffi, PyNativeType, Python, ToPyObject};
/// Represents a Python `dict`. /// Represents a Python `dict`.
#[repr(transparent)] #[repr(transparent)]
@ -82,26 +82,24 @@ impl PyDict {
/// ///
/// This is equivalent to the Python expression `self.copy()`. /// This is equivalent to the Python expression `self.copy()`.
pub fn copy(&self) -> PyResult<&PyDict> { pub fn copy(&self) -> PyResult<&PyDict> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().copy().map(Bound::into_gil_ref)
.copy()
.map(Bound::into_gil_ref)
} }
/// Empties an existing dictionary of all key-value pairs. /// Empties an existing dictionary of all key-value pairs.
pub fn clear(&self) { pub fn clear(&self) {
Bound::borrowed_from_gil_ref(&self).clear() self.as_borrowed().clear()
} }
/// Return the number of items in the dictionary. /// Return the number of items in the dictionary.
/// ///
/// This is equivalent to the Python expression `len(self)`. /// This is equivalent to the Python expression `len(self)`.
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
Bound::borrowed_from_gil_ref(&self).len() self.as_borrowed().len()
} }
/// Checks if the dict is empty, i.e. `len(self) == 0`. /// Checks if the dict is empty, i.e. `len(self) == 0`.
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).is_empty() self.as_borrowed().is_empty()
} }
/// Determines if the dictionary contains the specified key. /// Determines if the dictionary contains the specified key.
@ -111,7 +109,7 @@ impl PyDict {
where where
K: ToPyObject, K: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).contains(key) self.as_borrowed().contains(key)
} }
/// Gets an item from the dictionary. /// Gets an item from the dictionary.
@ -160,7 +158,7 @@ impl PyDict {
where where
K: ToPyObject, K: ToPyObject,
{ {
match Bound::borrowed_from_gil_ref(&self).get_item(key) { match self.as_borrowed().get_item(key) {
Ok(Some(item)) => Ok(Some(item.into_gil_ref())), Ok(Some(item)) => Ok(Some(item.into_gil_ref())),
Ok(None) => Ok(None), Ok(None) => Ok(None),
Err(e) => Err(e), Err(e) => Err(e),
@ -188,7 +186,7 @@ impl PyDict {
K: ToPyObject, K: ToPyObject,
V: ToPyObject, V: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).set_item(key, value) self.as_borrowed().set_item(key, value)
} }
/// Deletes an item. /// Deletes an item.
@ -198,28 +196,28 @@ impl PyDict {
where where
K: ToPyObject, K: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).del_item(key) self.as_borrowed().del_item(key)
} }
/// Returns a list of dict keys. /// Returns a list of dict keys.
/// ///
/// This is equivalent to the Python expression `list(dict.keys())`. /// This is equivalent to the Python expression `list(dict.keys())`.
pub fn keys(&self) -> &PyList { pub fn keys(&self) -> &PyList {
Bound::borrowed_from_gil_ref(&self).keys().into_gil_ref() self.as_borrowed().keys().into_gil_ref()
} }
/// Returns a list of dict values. /// Returns a list of dict values.
/// ///
/// This is equivalent to the Python expression `list(dict.values())`. /// This is equivalent to the Python expression `list(dict.values())`.
pub fn values(&self) -> &PyList { pub fn values(&self) -> &PyList {
Bound::borrowed_from_gil_ref(&self).values().into_gil_ref() self.as_borrowed().values().into_gil_ref()
} }
/// Returns a list of dict items. /// Returns a list of dict items.
/// ///
/// This is equivalent to the Python expression `list(dict.items())`. /// This is equivalent to the Python expression `list(dict.items())`.
pub fn items(&self) -> &PyList { pub fn items(&self) -> &PyList {
Bound::borrowed_from_gil_ref(&self).items().into_gil_ref() self.as_borrowed().items().into_gil_ref()
} }
/// Returns an iterator of `(key, value)` pairs in this dictionary. /// Returns an iterator of `(key, value)` pairs in this dictionary.
@ -230,7 +228,7 @@ impl PyDict {
/// It is allowed to modify values as you iterate over the dictionary, but only /// It is allowed to modify values as you iterate over the dictionary, but only
/// so long as the set of keys does not change. /// so long as the set of keys does not change.
pub fn iter(&self) -> PyDictIterator<'_> { pub fn iter(&self) -> PyDictIterator<'_> {
PyDictIterator(Bound::borrowed_from_gil_ref(&self).iter()) PyDictIterator(self.as_borrowed().iter())
} }
/// Returns `self` cast as a `PyMapping`. /// Returns `self` cast as a `PyMapping`.
@ -243,7 +241,7 @@ impl PyDict {
/// This is equivalent to the Python expression `self.update(other)`. If `other` is a `PyDict`, you may want /// This is equivalent to the Python expression `self.update(other)`. If `other` is a `PyDict`, you may want
/// to use `self.update(other.as_mapping())`, note: `PyDict::as_mapping` is a zero-cost conversion. /// to use `self.update(other.as_mapping())`, note: `PyDict::as_mapping` is a zero-cost conversion.
pub fn update(&self, other: &PyMapping) -> PyResult<()> { pub fn update(&self, other: &PyMapping) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).update(Bound::borrowed_from_gil_ref(&other)) self.as_borrowed().update(&other.as_borrowed())
} }
/// Add key/value pairs from another dictionary to this one only when they do not exist in this. /// Add key/value pairs from another dictionary to this one only when they do not exist in this.
@ -255,7 +253,7 @@ impl PyDict {
/// This method uses [`PyDict_Merge`](https://docs.python.org/3/c-api/dict.html#c.PyDict_Merge) internally, /// This method uses [`PyDict_Merge`](https://docs.python.org/3/c-api/dict.html#c.PyDict_Merge) internally,
/// so should have the same performance as `update`. /// so should have the same performance as `update`.
pub fn update_if_missing(&self, other: &PyMapping) -> PyResult<()> { pub fn update_if_missing(&self, other: &PyMapping) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).update_if_missing(Bound::borrowed_from_gil_ref(&other)) self.as_borrowed().update_if_missing(&other.as_borrowed())
} }
} }

View file

@ -29,7 +29,7 @@ impl PyFloat {
/// Gets the value of this float. /// Gets the value of this float.
pub fn value(&self) -> c_double { pub fn value(&self) -> c_double {
Bound::borrowed_from_gil_ref(&self).value() self.as_borrowed().value()
} }
} }

View file

@ -35,7 +35,7 @@ impl PyIterator {
/// ///
/// Equivalent to Python's built-in `iter` function. /// Equivalent to Python's built-in `iter` function.
pub fn from_object(obj: &PyAny) -> PyResult<&PyIterator> { pub fn from_object(obj: &PyAny) -> PyResult<&PyIterator> {
Self::from_object2(Bound::borrowed_from_gil_ref(&obj)).map(Bound::into_gil_ref) Self::from_object2(&obj.as_borrowed()).map(Bound::into_gil_ref)
} }
pub(crate) fn from_object2<'py>(obj: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyIterator>> { pub(crate) fn from_object2<'py>(obj: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyIterator>> {
@ -57,14 +57,14 @@ impl<'p> Iterator for &'p PyIterator {
/// Further `next()` calls after an exception occurs are likely /// Further `next()` calls after an exception occurs are likely
/// to repeatedly result in the same exception. /// to repeatedly result in the same exception.
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
Borrowed::<PyIterator>::from_gil_ref(self) self.as_borrowed()
.next() .next()
.map(|result| result.map(Bound::into_gil_ref)) .map(|result| result.map(Bound::into_gil_ref))
} }
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
Bound::borrowed_from_gil_ref(self).size_hint() self.as_borrowed().size_hint()
} }
} }

View file

@ -7,7 +7,7 @@ use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::Borrowed; use crate::instance::Borrowed;
use crate::internal_tricks::get_ssize_index; use crate::internal_tricks::get_ssize_index;
use crate::types::{PySequence, PyTuple}; use crate::types::{PySequence, PyTuple};
use crate::{Bound, PyAny, PyObject, Python, ToPyObject}; use crate::{Bound, PyAny, PyNativeType, PyObject, Python, ToPyObject};
use crate::types::any::PyAnyMethods; use crate::types::any::PyAnyMethods;
use crate::types::sequence::PySequenceMethods; use crate::types::sequence::PySequenceMethods;
@ -98,12 +98,12 @@ impl PyList {
/// Returns the length of the list. /// Returns the length of the list.
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
Bound::borrowed_from_gil_ref(&self).len() self.as_borrowed().len()
} }
/// Checks if the list is empty. /// Checks if the list is empty.
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).is_empty() self.as_borrowed().is_empty()
} }
/// Returns `self` cast as a `PySequence`. /// Returns `self` cast as a `PySequence`.
@ -122,9 +122,7 @@ impl PyList {
/// }); /// });
/// ``` /// ```
pub fn get_item(&self, index: usize) -> PyResult<&PyAny> { pub fn get_item(&self, index: usize) -> PyResult<&PyAny> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().get_item(index).map(Bound::into_gil_ref)
.get_item(index)
.map(Bound::into_gil_ref)
} }
/// Gets the list item at the specified index. Undefined behavior on bad index. Use with caution. /// Gets the list item at the specified index. Undefined behavior on bad index. Use with caution.
@ -134,9 +132,7 @@ impl PyList {
/// Caller must verify that the index is within the bounds of the list. /// Caller must verify that the index is within the bounds of the list.
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
pub unsafe fn get_item_unchecked(&self, index: usize) -> &PyAny { pub unsafe fn get_item_unchecked(&self, index: usize) -> &PyAny {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().get_item_unchecked(index).into_gil_ref()
.get_item_unchecked(index)
.into_gil_ref()
} }
/// Takes the slice `self[low:high]` and returns it as a new list. /// Takes the slice `self[low:high]` and returns it as a new list.
@ -144,9 +140,7 @@ impl PyList {
/// Indices must be nonnegative, and out-of-range indices are clipped to /// Indices must be nonnegative, and out-of-range indices are clipped to
/// `self.len()`. /// `self.len()`.
pub fn get_slice(&self, low: usize, high: usize) -> &PyList { pub fn get_slice(&self, low: usize, high: usize) -> &PyList {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().get_slice(low, high).into_gil_ref()
.get_slice(low, high)
.into_gil_ref()
} }
/// Sets the item at the specified index. /// Sets the item at the specified index.
@ -156,7 +150,7 @@ impl PyList {
where where
I: ToPyObject, I: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).set_item(index, item) self.as_borrowed().set_item(index, item)
} }
/// Deletes the `index`th element of self. /// Deletes the `index`th element of self.
@ -164,7 +158,7 @@ impl PyList {
/// This is equivalent to the Python statement `del self[i]`. /// This is equivalent to the Python statement `del self[i]`.
#[inline] #[inline]
pub fn del_item(&self, index: usize) -> PyResult<()> { pub fn del_item(&self, index: usize) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).del_item(index) self.as_borrowed().del_item(index)
} }
/// Assigns the sequence `seq` to the slice of `self` from `low` to `high`. /// Assigns the sequence `seq` to the slice of `self` from `low` to `high`.
@ -172,7 +166,7 @@ impl PyList {
/// This is equivalent to the Python statement `self[low:high] = v`. /// This is equivalent to the Python statement `self[low:high] = v`.
#[inline] #[inline]
pub fn set_slice(&self, low: usize, high: usize, seq: &PyAny) -> PyResult<()> { pub fn set_slice(&self, low: usize, high: usize, seq: &PyAny) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).set_slice(low, high, Bound::borrowed_from_gil_ref(&seq)) self.as_borrowed().set_slice(low, high, &seq.as_borrowed())
} }
/// Deletes the slice from `low` to `high` from `self`. /// Deletes the slice from `low` to `high` from `self`.
@ -180,7 +174,7 @@ impl PyList {
/// This is equivalent to the Python statement `del self[low:high]`. /// This is equivalent to the Python statement `del self[low:high]`.
#[inline] #[inline]
pub fn del_slice(&self, low: usize, high: usize) -> PyResult<()> { pub fn del_slice(&self, low: usize, high: usize) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).del_slice(low, high) self.as_borrowed().del_slice(low, high)
} }
/// Appends an item to the list. /// Appends an item to the list.
@ -188,7 +182,7 @@ impl PyList {
where where
I: ToPyObject, I: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).append(item) self.as_borrowed().append(item)
} }
/// Inserts an item at the specified index. /// Inserts an item at the specified index.
@ -198,7 +192,7 @@ impl PyList {
where where
I: ToPyObject, I: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).insert(index, item) self.as_borrowed().insert(index, item)
} }
/// Determines if self contains `value`. /// Determines if self contains `value`.
@ -209,7 +203,7 @@ impl PyList {
where where
V: ToPyObject, V: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).contains(value) self.as_borrowed().contains(value)
} }
/// Returns the first index `i` for which `self[i] == value`. /// Returns the first index `i` for which `self[i] == value`.
@ -220,31 +214,29 @@ impl PyList {
where where
V: ToPyObject, V: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).index(value) self.as_borrowed().index(value)
} }
/// Returns an iterator over this list's items. /// Returns an iterator over this list's items.
pub fn iter(&self) -> PyListIterator<'_> { pub fn iter(&self) -> PyListIterator<'_> {
PyListIterator(Bound::borrowed_from_gil_ref(&self).iter()) PyListIterator(self.as_borrowed().iter())
} }
/// Sorts the list in-place. Equivalent to the Python expression `l.sort()`. /// Sorts the list in-place. Equivalent to the Python expression `l.sort()`.
pub fn sort(&self) -> PyResult<()> { pub fn sort(&self) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).sort() self.as_borrowed().sort()
} }
/// Reverses the list in-place. Equivalent to the Python expression `l.reverse()`. /// Reverses the list in-place. Equivalent to the Python expression `l.reverse()`.
pub fn reverse(&self) -> PyResult<()> { pub fn reverse(&self) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).reverse() self.as_borrowed().reverse()
} }
/// Return a new tuple containing the contents of the list; equivalent to the Python expression `tuple(list)`. /// Return a new tuple containing the contents of the list; equivalent to the Python expression `tuple(list)`.
/// ///
/// This method is equivalent to `self.as_sequence().to_tuple()` and faster than `PyTuple::new(py, this_list)`. /// This method is equivalent to `self.as_sequence().to_tuple()` and faster than `PyTuple::new(py, this_list)`.
pub fn to_tuple(&self) -> &PyTuple { pub fn to_tuple(&self) -> &PyTuple {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().to_tuple().into_gil_ref()
.to_tuple()
.into_gil_ref()
} }
} }

View file

@ -20,13 +20,13 @@ impl PyMapping {
/// This is equivalent to the Python expression `len(self)`. /// This is equivalent to the Python expression `len(self)`.
#[inline] #[inline]
pub fn len(&self) -> PyResult<usize> { pub fn len(&self) -> PyResult<usize> {
Bound::borrowed_from_gil_ref(&self).len() self.as_borrowed().len()
} }
/// Returns whether the mapping is empty. /// Returns whether the mapping is empty.
#[inline] #[inline]
pub fn is_empty(&self) -> PyResult<bool> { pub fn is_empty(&self) -> PyResult<bool> {
Bound::borrowed_from_gil_ref(&self).is_empty() self.as_borrowed().is_empty()
} }
/// Determines if the mapping contains the specified key. /// Determines if the mapping contains the specified key.
@ -36,7 +36,7 @@ impl PyMapping {
where where
K: ToPyObject, K: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).contains(key) self.as_borrowed().contains(key)
} }
/// Gets the item in self with key `key`. /// Gets the item in self with key `key`.
@ -49,9 +49,7 @@ impl PyMapping {
where where
K: ToPyObject, K: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().get_item(key).map(Bound::into_gil_ref)
.get_item(key)
.map(Bound::into_gil_ref)
} }
/// Sets the item in self with key `key`. /// Sets the item in self with key `key`.
@ -63,7 +61,7 @@ impl PyMapping {
K: ToPyObject, K: ToPyObject,
V: ToPyObject, V: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).set_item(key, value) self.as_borrowed().set_item(key, value)
} }
/// Deletes the item with key `key`. /// Deletes the item with key `key`.
@ -74,31 +72,25 @@ impl PyMapping {
where where
K: ToPyObject, K: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).del_item(key) self.as_borrowed().del_item(key)
} }
/// Returns a sequence containing all keys in the mapping. /// Returns a sequence containing all keys in the mapping.
#[inline] #[inline]
pub fn keys(&self) -> PyResult<&PySequence> { pub fn keys(&self) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().keys().map(Bound::into_gil_ref)
.keys()
.map(Bound::into_gil_ref)
} }
/// Returns a sequence containing all values in the mapping. /// Returns a sequence containing all values in the mapping.
#[inline] #[inline]
pub fn values(&self) -> PyResult<&PySequence> { pub fn values(&self) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().values().map(Bound::into_gil_ref)
.values()
.map(Bound::into_gil_ref)
} }
/// Returns a sequence of tuples of all (key, value) pairs in the mapping. /// Returns a sequence of tuples of all (key, value) pairs in the mapping.
#[inline] #[inline]
pub fn items(&self) -> PyResult<&PySequence> { pub fn items(&self) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().items().map(Bound::into_gil_ref)
.items()
.map(Bound::into_gil_ref)
} }
/// Register a pyclass as a subclass of `collections.abc.Mapping` (from the Python standard /// Register a pyclass as a subclass of `collections.abc.Mapping` (from the Python standard
@ -257,10 +249,7 @@ impl PyTypeCheck for PyMapping {
|| get_mapping_abc(object.py()) || get_mapping_abc(object.py())
.and_then(|abc| object.is_instance(abc)) .and_then(|abc| object.is_instance(abc))
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
err.write_unraisable_bound( err.write_unraisable_bound(object.py(), Some(&object.as_borrowed()));
object.py(),
Some(Bound::borrowed_from_gil_ref(&object)),
);
false false
}) })
} }

View file

@ -105,9 +105,10 @@ macro_rules! pyobject_native_type_base(
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>)
-> ::std::result::Result<(), ::std::fmt::Error> -> ::std::result::Result<(), ::std::fmt::Error>
{ {
use $crate::PyNativeType;
match self.str() { match self.str() {
::std::result::Result::Ok(s) => return f.write_str(&s.to_string_lossy()), ::std::result::Result::Ok(s) => return f.write_str(&s.to_string_lossy()),
::std::result::Result::Err(err) => err.write_unraisable_bound(self.py(), ::std::option::Option::Some($crate::Bound::borrowed_from_gil_ref(&self))), ::std::result::Result::Err(err) => err.write_unraisable_bound(self.py(), ::std::option::Option::Some(&self.as_borrowed())),
} }
match self.get_type().name() { match self.get_type().name() {

View file

@ -1,7 +1,7 @@
use crate::instance::Bound; use crate::instance::Bound;
use crate::types::any::PyAnyMethods; use crate::types::any::PyAnyMethods;
use crate::types::PyType; use crate::types::PyType;
use crate::{ffi, PyTypeInfo}; use crate::{ffi, PyNativeType, PyTypeInfo};
use crate::{PyAny, PyResult}; use crate::{PyAny, PyResult};
/// Represents a Python `super` object. /// Represents a Python `super` object.
@ -22,11 +22,7 @@ impl PySuper {
note = "`PySuper::new` will be replaced by `PySuper::new_bound` in a future PyO3 version" note = "`PySuper::new` will be replaced by `PySuper::new_bound` in a future PyO3 version"
)] )]
pub fn new<'py>(ty: &'py PyType, obj: &'py PyAny) -> PyResult<&'py PySuper> { pub fn new<'py>(ty: &'py PyType, obj: &'py PyAny) -> PyResult<&'py PySuper> {
Self::new_bound( Self::new_bound(&ty.as_borrowed(), &obj.as_borrowed()).map(Bound::into_gil_ref)
Bound::borrowed_from_gil_ref(&ty),
Bound::borrowed_from_gil_ref(&obj),
)
.map(Bound::into_gil_ref)
} }
/// Constructs a new super object. More read about super object: [docs](https://docs.python.org/3/library/functions.html#super) /// Constructs a new super object. More read about super object: [docs](https://docs.python.org/3/library/functions.html#super)
@ -73,7 +69,8 @@ impl PySuper {
ty: &Bound<'py, PyType>, ty: &Bound<'py, PyType>,
obj: &Bound<'py, PyAny>, obj: &Bound<'py, PyAny>,
) -> PyResult<Bound<'py, PySuper>> { ) -> PyResult<Bound<'py, PySuper>> {
Bound::borrowed_from_gil_ref(&PySuper::type_object(ty.py())) PySuper::type_object(ty.py())
.as_borrowed()
.call1((ty, obj)) .call1((ty, obj))
.map(|any| { .map(|any| {
// Safety: super() always returns instance of super // Safety: super() always returns instance of super

View file

@ -23,13 +23,13 @@ impl PySequence {
/// This is equivalent to the Python expression `len(self)`. /// This is equivalent to the Python expression `len(self)`.
#[inline] #[inline]
pub fn len(&self) -> PyResult<usize> { pub fn len(&self) -> PyResult<usize> {
Bound::borrowed_from_gil_ref(&self).len() self.as_borrowed().len()
} }
/// Returns whether the sequence is empty. /// Returns whether the sequence is empty.
#[inline] #[inline]
pub fn is_empty(&self) -> PyResult<bool> { pub fn is_empty(&self) -> PyResult<bool> {
Bound::borrowed_from_gil_ref(&self).is_empty() self.as_borrowed().is_empty()
} }
/// Returns the concatenation of `self` and `other`. /// Returns the concatenation of `self` and `other`.
@ -37,8 +37,8 @@ impl PySequence {
/// This is equivalent to the Python expression `self + other`. /// This is equivalent to the Python expression `self + other`.
#[inline] #[inline]
pub fn concat(&self, other: &PySequence) -> PyResult<&PySequence> { pub fn concat(&self, other: &PySequence) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed()
.concat(Bound::borrowed_from_gil_ref(&other)) .concat(&other.as_borrowed())
.map(Bound::into_gil_ref) .map(Bound::into_gil_ref)
} }
@ -47,9 +47,7 @@ impl PySequence {
/// This is equivalent to the Python expression `self * count`. /// This is equivalent to the Python expression `self * count`.
#[inline] #[inline]
pub fn repeat(&self, count: usize) -> PyResult<&PySequence> { pub fn repeat(&self, count: usize) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().repeat(count).map(Bound::into_gil_ref)
.repeat(count)
.map(Bound::into_gil_ref)
} }
/// Concatenates `self` and `other`, in place if possible. /// Concatenates `self` and `other`, in place if possible.
@ -61,8 +59,8 @@ impl PySequence {
/// possible, but create and return a new object if not. /// possible, but create and return a new object if not.
#[inline] #[inline]
pub fn in_place_concat(&self, other: &PySequence) -> PyResult<&PySequence> { pub fn in_place_concat(&self, other: &PySequence) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed()
.in_place_concat(Bound::borrowed_from_gil_ref(&other)) .in_place_concat(&other.as_borrowed())
.map(Bound::into_gil_ref) .map(Bound::into_gil_ref)
} }
@ -75,7 +73,7 @@ impl PySequence {
/// possible, but create and return a new object if not. /// possible, but create and return a new object if not.
#[inline] #[inline]
pub fn in_place_repeat(&self, count: usize) -> PyResult<&PySequence> { pub fn in_place_repeat(&self, count: usize) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed()
.in_place_repeat(count) .in_place_repeat(count)
.map(Bound::into_gil_ref) .map(Bound::into_gil_ref)
} }
@ -85,9 +83,7 @@ impl PySequence {
/// This is equivalent to the Python expression `self[index]` without support of negative indices. /// This is equivalent to the Python expression `self[index]` without support of negative indices.
#[inline] #[inline]
pub fn get_item(&self, index: usize) -> PyResult<&PyAny> { pub fn get_item(&self, index: usize) -> PyResult<&PyAny> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().get_item(index).map(Bound::into_gil_ref)
.get_item(index)
.map(|py2| py2.into_gil_ref())
} }
/// Returns the slice of sequence object between `begin` and `end`. /// Returns the slice of sequence object between `begin` and `end`.
@ -95,7 +91,7 @@ impl PySequence {
/// This is equivalent to the Python expression `self[begin:end]`. /// This is equivalent to the Python expression `self[begin:end]`.
#[inline] #[inline]
pub fn get_slice(&self, begin: usize, end: usize) -> PyResult<&PySequence> { pub fn get_slice(&self, begin: usize, end: usize) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed()
.get_slice(begin, end) .get_slice(begin, end)
.map(Bound::into_gil_ref) .map(Bound::into_gil_ref)
} }
@ -108,7 +104,7 @@ impl PySequence {
where where
I: ToPyObject, I: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).set_item(i, item) self.as_borrowed().set_item(i, item)
} }
/// Deletes the `i`th element of self. /// Deletes the `i`th element of self.
@ -116,7 +112,7 @@ impl PySequence {
/// This is equivalent to the Python statement `del self[i]`. /// This is equivalent to the Python statement `del self[i]`.
#[inline] #[inline]
pub fn del_item(&self, i: usize) -> PyResult<()> { pub fn del_item(&self, i: usize) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).del_item(i) self.as_borrowed().del_item(i)
} }
/// Assigns the sequence `v` to the slice of `self` from `i1` to `i2`. /// Assigns the sequence `v` to the slice of `self` from `i1` to `i2`.
@ -124,7 +120,7 @@ impl PySequence {
/// This is equivalent to the Python statement `self[i1:i2] = v`. /// This is equivalent to the Python statement `self[i1:i2] = v`.
#[inline] #[inline]
pub fn set_slice(&self, i1: usize, i2: usize, v: &PyAny) -> PyResult<()> { pub fn set_slice(&self, i1: usize, i2: usize, v: &PyAny) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).set_slice(i1, i2, Bound::borrowed_from_gil_ref(&v)) self.as_borrowed().set_slice(i1, i2, &v.as_borrowed())
} }
/// Deletes the slice from `i1` to `i2` from `self`. /// Deletes the slice from `i1` to `i2` from `self`.
@ -132,7 +128,7 @@ impl PySequence {
/// This is equivalent to the Python statement `del self[i1:i2]`. /// This is equivalent to the Python statement `del self[i1:i2]`.
#[inline] #[inline]
pub fn del_slice(&self, i1: usize, i2: usize) -> PyResult<()> { pub fn del_slice(&self, i1: usize, i2: usize) -> PyResult<()> {
Bound::borrowed_from_gil_ref(&self).del_slice(i1, i2) self.as_borrowed().del_slice(i1, i2)
} }
/// Returns the number of occurrences of `value` in self, that is, return the /// Returns the number of occurrences of `value` in self, that is, return the
@ -143,7 +139,7 @@ impl PySequence {
where where
V: ToPyObject, V: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).count(value) self.as_borrowed().count(value)
} }
/// Determines if self contains `value`. /// Determines if self contains `value`.
@ -154,7 +150,7 @@ impl PySequence {
where where
V: ToPyObject, V: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).contains(value) self.as_borrowed().contains(value)
} }
/// Returns the first index `i` for which `self[i] == value`. /// Returns the first index `i` for which `self[i] == value`.
@ -165,23 +161,19 @@ impl PySequence {
where where
V: ToPyObject, V: ToPyObject,
{ {
Bound::borrowed_from_gil_ref(&self).index(value) self.as_borrowed().index(value)
} }
/// Returns a fresh list based on the Sequence. /// Returns a fresh list based on the Sequence.
#[inline] #[inline]
pub fn to_list(&self) -> PyResult<&PyList> { pub fn to_list(&self) -> PyResult<&PyList> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().to_list().map(Bound::into_gil_ref)
.to_list()
.map(|py2| py2.into_gil_ref())
} }
/// Returns a fresh tuple based on the Sequence. /// Returns a fresh tuple based on the Sequence.
#[inline] #[inline]
pub fn to_tuple(&self) -> PyResult<&PyTuple> { pub fn to_tuple(&self) -> PyResult<&PyTuple> {
Bound::borrowed_from_gil_ref(&self) self.as_borrowed().to_tuple().map(Bound::into_gil_ref)
.to_tuple()
.map(|py2| py2.into_gil_ref())
} }
/// Register a pyclass as a subclass of `collections.abc.Sequence` (from the Python standard /// Register a pyclass as a subclass of `collections.abc.Sequence` (from the Python standard
@ -541,10 +533,7 @@ impl PyTypeCheck for PySequence {
|| get_sequence_abc(object.py()) || get_sequence_abc(object.py())
.and_then(|abc| object.is_instance(abc)) .and_then(|abc| object.is_instance(abc))
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
err.write_unraisable_bound( err.write_unraisable_bound(object.py(), Some(&object.as_borrowed()));
object.py(),
Some(Bound::borrowed_from_gil_ref(&object)),
);
false false
}) })
} }

View file

@ -5,7 +5,7 @@ use crate::instance::Borrowed;
use crate::types::any::PyAnyMethods; use crate::types::any::PyAnyMethods;
use crate::types::bytes::PyBytesMethods; use crate::types::bytes::PyBytesMethods;
use crate::types::PyBytes; use crate::types::PyBytes;
use crate::{ffi, Bound, IntoPy, Py, PyAny, PyResult, Python}; use crate::{ffi, Bound, IntoPy, Py, PyAny, PyNativeType, PyResult, Python};
use std::borrow::Cow; use std::borrow::Cow;
use std::os::raw::c_char; use std::os::raw::c_char;
use std::str; use std::str;
@ -184,7 +184,7 @@ impl PyString {
pub fn to_str(&self) -> PyResult<&str> { pub fn to_str(&self) -> PyResult<&str> {
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))] #[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
{ {
Borrowed::from_gil_ref(self).to_str() self.as_borrowed().to_str()
} }
#[cfg(not(any(Py_3_10, not(Py_LIMITED_API))))] #[cfg(not(any(Py_3_10, not(Py_LIMITED_API))))]
@ -202,7 +202,7 @@ impl PyString {
/// Returns a `UnicodeEncodeError` if the input is not valid unicode /// Returns a `UnicodeEncodeError` if the input is not valid unicode
/// (containing unpaired surrogates). /// (containing unpaired surrogates).
pub fn to_cow(&self) -> PyResult<Cow<'_, str>> { pub fn to_cow(&self) -> PyResult<Cow<'_, str>> {
Borrowed::from_gil_ref(self).to_cow() self.as_borrowed().to_cow()
} }
/// Converts the `PyString` into a Rust string. /// Converts the `PyString` into a Rust string.
@ -210,7 +210,7 @@ impl PyString {
/// Unpaired surrogates invalid UTF-8 sequences are /// Unpaired surrogates invalid UTF-8 sequences are
/// replaced with `U+FFFD REPLACEMENT CHARACTER`. /// replaced with `U+FFFD REPLACEMENT CHARACTER`.
pub fn to_string_lossy(&self) -> Cow<'_, str> { pub fn to_string_lossy(&self) -> Cow<'_, str> {
Borrowed::from_gil_ref(self).to_string_lossy() self.as_borrowed().to_string_lossy()
} }
/// Obtains the raw data backing the Python string. /// Obtains the raw data backing the Python string.
@ -229,7 +229,7 @@ impl PyString {
/// expected on the targets where you plan to distribute your software. /// expected on the targets where you plan to distribute your software.
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
pub unsafe fn data(&self) -> PyResult<PyStringData<'_>> { pub unsafe fn data(&self) -> PyResult<PyStringData<'_>> {
Borrowed::from_gil_ref(self).data() self.as_borrowed().data()
} }
} }
@ -280,20 +280,20 @@ pub trait PyStringMethods<'py> {
impl<'py> PyStringMethods<'py> for Bound<'py, PyString> { impl<'py> PyStringMethods<'py> for Bound<'py, PyString> {
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))] #[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
fn to_str(&self) -> PyResult<&str> { fn to_str(&self) -> PyResult<&str> {
Borrowed::from(self).to_str() self.as_borrowed().to_str()
} }
fn to_cow(&self) -> PyResult<Cow<'_, str>> { fn to_cow(&self) -> PyResult<Cow<'_, str>> {
Borrowed::from(self).to_cow() self.as_borrowed().to_cow()
} }
fn to_string_lossy(&self) -> Cow<'_, str> { fn to_string_lossy(&self) -> Cow<'_, str> {
Borrowed::from(self).to_string_lossy() self.as_borrowed().to_string_lossy()
} }
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
unsafe fn data(&self) -> PyResult<PyStringData<'_>> { unsafe fn data(&self) -> PyResult<PyStringData<'_>> {
Borrowed::from(self).data() self.as_borrowed().data()
} }
} }