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::instance::Bound;
#[cfg(Py_LIMITED_API)]
use crate::sync::GILOnceCell;
#[cfg(not(Py_LIMITED_API))]
@ -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,
@ -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()))
};
}

View File

@ -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;
@ -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.
@ -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)
}
}

View File

@ -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(&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.
#[inline]
fn py(&self) -> Python<'_> {
@ -184,16 +197,13 @@ 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>` to a `Borrowed<T>` smart pointer.
pub fn as_borrowed<'a>(&'a self) -> Borrowed<'a, 'py, T> {
Borrowed(
unsafe { NonNull::new_unchecked(self.as_ptr()) },
PhantomData,
self.py(),
)
}
/// 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> {
/// Create borrow on a Bound
fn from(instance: &'a Bound<'py, T>) -> Self {
Self(
unsafe { NonNull::new_unchecked(instance.as_ptr()) },
PhantomData,
instance.py(),
)
instance.as_borrowed()
}
}
@ -311,12 +317,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()) }
@ -1366,7 +1366,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)
@ -1485,7 +1485,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() {
@ -1612,8 +1612,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);

View File

@ -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};

View File

@ -73,7 +73,7 @@ impl PyAny {
/// This is equivalent to the Python expression `self is other`.
#[inline]
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.
@ -102,7 +102,7 @@ impl PyAny {
where
N: IntoPy<Py<PyString>>,
{
Bound::borrowed_from_gil_ref(&self).hasattr(attr_name)
self.as_borrowed().hasattr(attr_name)
}
/// Retrieves an attribute value.
@ -131,7 +131,7 @@ impl PyAny {
where
N: IntoPy<Py<PyString>>,
{
Bound::borrowed_from_gil_ref(&self)
self.as_borrowed()
.getattr(attr_name)
.map(Bound::into_gil_ref)
}
@ -208,7 +208,7 @@ impl PyAny {
N: IntoPy<Py<PyString>>,
V: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).setattr(attr_name, value)
self.as_borrowed().setattr(attr_name, value)
}
/// Deletes an attribute.
@ -221,7 +221,7 @@ impl PyAny {
where
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`.
@ -274,7 +274,7 @@ impl PyAny {
where
O: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).compare(other)
self.as_borrowed().compare(other)
}
/// Tests whether two Python objects obey a given [`CompareOp`].
@ -315,7 +315,7 @@ impl PyAny {
where
O: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self)
self.as_borrowed()
.rich_compare(other, compare_op)
.map(Bound::into_gil_ref)
}
@ -327,7 +327,7 @@ impl PyAny {
where
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.
@ -337,7 +337,7 @@ impl PyAny {
where
O: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).le(other)
self.as_borrowed().le(other)
}
/// Tests whether this object is equal to another.
@ -347,7 +347,7 @@ impl PyAny {
where
O: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).eq(other)
self.as_borrowed().eq(other)
}
/// Tests whether this object is not equal to another.
@ -357,7 +357,7 @@ impl PyAny {
where
O: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).ne(other)
self.as_borrowed().ne(other)
}
/// Tests whether this object is greater than another.
@ -367,7 +367,7 @@ impl PyAny {
where
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.
@ -377,7 +377,7 @@ impl PyAny {
where
O: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).ge(other)
self.as_borrowed().ge(other)
}
/// Determines whether this object appears callable.
@ -408,7 +408,7 @@ impl PyAny {
///
/// [1]: https://docs.python.org/3/library/functions.html#callable
pub fn is_callable(&self) -> bool {
Bound::borrowed_from_gil_ref(&self).is_callable()
self.as_borrowed().is_callable()
}
/// Calls the object.
@ -446,7 +446,7 @@ impl PyAny {
args: impl IntoPy<Py<PyTuple>>,
kwargs: Option<&PyDict>,
) -> PyResult<&PyAny> {
Bound::borrowed_from_gil_ref(&self)
self.as_borrowed()
.call(args, kwargs)
.map(Bound::into_gil_ref)
}
@ -472,9 +472,7 @@ impl PyAny {
///
/// This is equivalent to the Python expression `help()`.
pub fn call0(&self) -> PyResult<&PyAny> {
Bound::borrowed_from_gil_ref(&self)
.call0()
.map(Bound::into_gil_ref)
self.as_borrowed().call0().map(Bound::into_gil_ref)
}
/// Calls the object with only positional arguments.
@ -505,9 +503,7 @@ impl PyAny {
/// # }
/// ```
pub fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyAny> {
Bound::borrowed_from_gil_ref(&self)
.call1(args)
.map(Bound::into_gil_ref)
self.as_borrowed().call1(args).map(Bound::into_gil_ref)
}
/// Calls a method on the object.
@ -550,7 +546,7 @@ impl PyAny {
N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>,
{
Bound::borrowed_from_gil_ref(&self)
self.as_borrowed()
.call_method(name, args, kwargs)
.map(Bound::into_gil_ref)
}
@ -590,7 +586,7 @@ impl PyAny {
where
N: IntoPy<Py<PyString>>,
{
Bound::borrowed_from_gil_ref(&self)
self.as_borrowed()
.call_method0(name)
.map(Bound::into_gil_ref)
}
@ -632,7 +628,7 @@ impl PyAny {
N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>,
{
Bound::borrowed_from_gil_ref(&self)
self.as_borrowed()
.call_method1(name, args)
.map(Bound::into_gil_ref)
}
@ -649,7 +645,7 @@ impl PyAny {
///
/// This applies truth value testing equivalent to the Python expression `bool(self)`.
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.
@ -657,7 +653,7 @@ impl PyAny {
/// This is equivalent to the Python expression `self is None`.
#[inline]
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. `...`.
@ -665,14 +661,14 @@ impl PyAny {
/// This is equivalent to the Python expression `self is ...`.
#[deprecated(since = "0.20.0", note = "use `.is(py.Ellipsis())` instead")]
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.
///
/// This is equivalent to the Python expression `len(self) == 0`.
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.
@ -682,9 +678,7 @@ impl PyAny {
where
K: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self)
.get_item(key)
.map(Bound::into_gil_ref)
self.as_borrowed().get_item(key).map(Bound::into_gil_ref)
}
/// Sets a collection item value.
@ -695,7 +689,7 @@ impl PyAny {
K: 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.
@ -705,7 +699,7 @@ impl PyAny {
where
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.
@ -713,20 +707,18 @@ impl PyAny {
/// This is typically a new iterator but if the argument is an iterator,
/// this returns itself.
pub fn iter(&self) -> PyResult<&PyIterator> {
Bound::borrowed_from_gil_ref(&self)
.iter()
.map(Bound::into_gil_ref)
self.as_borrowed().iter().map(Bound::into_gil_ref)
}
/// Returns the Python type object for this object's type.
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.
#[inline]
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.
@ -863,46 +855,42 @@ impl PyAny {
/// Returns the reference count for the Python object.
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.
///
/// This is equivalent to the Python expression `repr(self)`.
pub fn repr(&self) -> PyResult<&PyString> {
Bound::borrowed_from_gil_ref(&self)
.repr()
.map(Bound::into_gil_ref)
self.as_borrowed().repr().map(Bound::into_gil_ref)
}
/// Computes the "str" representation of self.
///
/// This is equivalent to the Python expression `str(self)`.
pub fn str(&self) -> PyResult<&PyString> {
Bound::borrowed_from_gil_ref(&self)
.str()
.map(Bound::into_gil_ref)
self.as_borrowed().str().map(Bound::into_gil_ref)
}
/// Retrieves the hash code of self.
///
/// This is equivalent to the Python expression `hash(self)`.
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.
///
/// This is equivalent to the Python expression `len(self)`.
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.
///
/// This is equivalent to the Python expression `dir(self)`.
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`.
@ -910,7 +898,7 @@ impl PyAny {
/// This is equivalent to the Python expression `isinstance(self, ty)`.
#[inline]
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).
@ -918,7 +906,7 @@ impl PyAny {
/// This is equivalent to the Python expression `type(self) is ty`.
#[inline]
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`.
@ -927,7 +915,7 @@ impl PyAny {
/// if the type `T` is known at compile time.
#[inline]
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`.
@ -936,7 +924,7 @@ impl PyAny {
/// if the type `T` is known at compile time.
#[inline]
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`.
@ -946,7 +934,7 @@ impl PyAny {
where
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.
@ -985,9 +973,7 @@ impl PyAny {
/// This is equivalent to the Python expression `super()`
#[cfg(not(PyPy))]
pub fn py_super(&self) -> PyResult<&PySuper> {
Bound::borrowed_from_gil_ref(&self)
.py_super()
.map(Bound::into_gil_ref)
self.as_borrowed().py_super().map(Bound::into_gil_ref)
}
}
@ -2193,7 +2179,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
#[cfg(not(PyPy))]
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")]
use crate::inspect::types::TypeInfo;
use crate::{
exceptions::PyTypeError, ffi, instance::Bound, FromPyObject, IntoPy, PyAny, PyObject, PyResult,
Python, ToPyObject,
exceptions::PyTypeError, ffi, instance::Bound, FromPyObject, IntoPy, PyAny, PyNativeType,
PyObject, PyResult, Python, ToPyObject,
};
/// Represents a Python `bool`.
@ -21,7 +21,7 @@ impl PyBool {
/// Gets whether this boolean is `true`.
#[inline]
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::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::slice;
@ -75,12 +75,12 @@ impl PyByteArray {
/// Gets the length of the bytearray.
#[inline]
pub fn len(&self) -> usize {
Bound::borrowed_from_gil_ref(&self).len()
self.as_borrowed().len()
}
/// Checks if the bytearray is empty.
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.
@ -89,7 +89,7 @@ impl PyByteArray {
///
/// See the safety requirements of [`PyByteArray::as_bytes`] and [`PyByteArray::as_bytes_mut`].
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.
@ -188,7 +188,7 @@ impl PyByteArray {
/// }
/// ```
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.
@ -200,7 +200,7 @@ impl PyByteArray {
/// apply to this function as well.
#[allow(clippy::mut_from_ref)]
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.
@ -222,7 +222,7 @@ impl PyByteArray {
/// # });
/// ```
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`.
@ -230,7 +230,7 @@ impl PyByteArray {
/// 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].
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 {
Borrowed::from(self).data()
self.as_borrowed().data()
}
unsafe fn as_bytes(&self) -> &[u8] {
Borrowed::from(self).as_bytes()
self.as_borrowed().as_bytes()
}
#[allow(clippy::mut_from_ref)]
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> {

View File

@ -1,5 +1,5 @@
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::ops::Index;
use std::os::raw::c_char;
@ -89,7 +89,7 @@ impl PyBytes {
/// Gets the Python string as a byte slice.
#[inline]
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> {
#[inline]
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 {
fn get_year(&self) -> i32 {
Bound::borrowed_from_gil_ref(&self).get_year()
self.as_borrowed().get_year()
}
fn get_month(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_month()
self.as_borrowed().get_month()
}
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 {
fn get_year(&self) -> i32 {
Bound::borrowed_from_gil_ref(&self).get_year()
self.as_borrowed().get_year()
}
fn get_month(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_month()
self.as_borrowed().get_month()
}
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 {
fn get_hour(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_hour()
self.as_borrowed().get_hour()
}
fn get_minute(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_minute()
self.as_borrowed().get_minute()
}
fn get_second(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_second()
self.as_borrowed().get_second()
}
fn get_microsecond(&self) -> u32 {
Bound::borrowed_from_gil_ref(&self).get_microsecond()
self.as_borrowed().get_microsecond()
}
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 {
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 {
fn get_hour(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_hour()
self.as_borrowed().get_hour()
}
fn get_minute(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_minute()
self.as_borrowed().get_minute()
}
fn get_second(&self) -> u8 {
Bound::borrowed_from_gil_ref(&self).get_second()
self.as_borrowed().get_second()
}
fn get_microsecond(&self) -> u32 {
Bound::borrowed_from_gil_ref(&self).get_microsecond()
self.as_borrowed().get_microsecond()
}
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 {
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 {
fn get_days(&self) -> i32 {
Bound::borrowed_from_gil_ref(&self).get_days()
self.as_borrowed().get_days()
}
fn get_seconds(&self) -> i32 {
Bound::borrowed_from_gil_ref(&self).get_seconds()
self.as_borrowed().get_seconds()
}
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::types::any::PyAnyMethods;
use crate::types::{PyAny, PyList};
use crate::{ffi, Python, ToPyObject};
use crate::{ffi, PyNativeType, Python, ToPyObject};
/// Represents a Python `dict`.
#[repr(transparent)]
@ -82,26 +82,24 @@ impl PyDict {
///
/// This is equivalent to the Python expression `self.copy()`.
pub fn copy(&self) -> PyResult<&PyDict> {
Bound::borrowed_from_gil_ref(&self)
.copy()
.map(Bound::into_gil_ref)
self.as_borrowed().copy().map(Bound::into_gil_ref)
}
/// Empties an existing dictionary of all key-value pairs.
pub fn clear(&self) {
Bound::borrowed_from_gil_ref(&self).clear()
self.as_borrowed().clear()
}
/// Return the number of items in the dictionary.
///
/// This is equivalent to the Python expression `len(self)`.
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`.
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.
@ -111,7 +109,7 @@ impl PyDict {
where
K: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).contains(key)
self.as_borrowed().contains(key)
}
/// Gets an item from the dictionary.
@ -160,7 +158,7 @@ impl PyDict {
where
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(None) => Ok(None),
Err(e) => Err(e),
@ -188,7 +186,7 @@ impl PyDict {
K: ToPyObject,
V: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).set_item(key, value)
self.as_borrowed().set_item(key, value)
}
/// Deletes an item.
@ -198,28 +196,28 @@ impl PyDict {
where
K: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).del_item(key)
self.as_borrowed().del_item(key)
}
/// Returns a list of dict keys.
///
/// This is equivalent to the Python expression `list(dict.keys())`.
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.
///
/// This is equivalent to the Python expression `list(dict.values())`.
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.
///
/// This is equivalent to the Python expression `list(dict.items())`.
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.
@ -230,7 +228,7 @@ impl PyDict {
/// It is allowed to modify values as you iterate over the dictionary, but only
/// so long as the set of keys does not change.
pub fn iter(&self) -> PyDictIterator<'_> {
PyDictIterator(Bound::borrowed_from_gil_ref(&self).iter())
PyDictIterator(self.as_borrowed().iter())
}
/// 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
/// to use `self.update(other.as_mapping())`, note: `PyDict::as_mapping` is a zero-cost conversion.
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.
@ -255,7 +253,7 @@ impl PyDict {
/// 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`.
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.
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.
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>> {
@ -57,14 +57,14 @@ impl<'p> Iterator for &'p PyIterator {
/// Further `next()` calls after an exception occurs are likely
/// to repeatedly result in the same exception.
fn next(&mut self) -> Option<Self::Item> {
Borrowed::<PyIterator>::from_gil_ref(self)
self.as_borrowed()
.next()
.map(|result| result.map(Bound::into_gil_ref))
}
#[cfg(not(Py_LIMITED_API))]
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::internal_tricks::get_ssize_index;
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::sequence::PySequenceMethods;
@ -98,12 +98,12 @@ impl PyList {
/// Returns the length of the list.
pub fn len(&self) -> usize {
Bound::borrowed_from_gil_ref(&self).len()
self.as_borrowed().len()
}
/// Checks if the list is empty.
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`.
@ -122,9 +122,7 @@ impl PyList {
/// });
/// ```
pub fn get_item(&self, index: usize) -> PyResult<&PyAny> {
Bound::borrowed_from_gil_ref(&self)
.get_item(index)
.map(Bound::into_gil_ref)
self.as_borrowed().get_item(index).map(Bound::into_gil_ref)
}
/// 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.
#[cfg(not(Py_LIMITED_API))]
pub unsafe fn get_item_unchecked(&self, index: usize) -> &PyAny {
Bound::borrowed_from_gil_ref(&self)
.get_item_unchecked(index)
.into_gil_ref()
self.as_borrowed().get_item_unchecked(index).into_gil_ref()
}
/// 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
/// `self.len()`.
pub fn get_slice(&self, low: usize, high: usize) -> &PyList {
Bound::borrowed_from_gil_ref(&self)
.get_slice(low, high)
.into_gil_ref()
self.as_borrowed().get_slice(low, high).into_gil_ref()
}
/// Sets the item at the specified index.
@ -156,7 +150,7 @@ impl PyList {
where
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.
@ -164,7 +158,7 @@ impl PyList {
/// This is equivalent to the Python statement `del self[i]`.
#[inline]
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`.
@ -172,7 +166,7 @@ impl PyList {
/// This is equivalent to the Python statement `self[low:high] = v`.
#[inline]
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`.
@ -180,7 +174,7 @@ impl PyList {
/// This is equivalent to the Python statement `del self[low:high]`.
#[inline]
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.
@ -188,7 +182,7 @@ impl PyList {
where
I: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).append(item)
self.as_borrowed().append(item)
}
/// Inserts an item at the specified index.
@ -198,7 +192,7 @@ impl PyList {
where
I: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).insert(index, item)
self.as_borrowed().insert(index, item)
}
/// Determines if self contains `value`.
@ -209,7 +203,7 @@ impl PyList {
where
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`.
@ -220,31 +214,29 @@ impl PyList {
where
V: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).index(value)
self.as_borrowed().index(value)
}
/// Returns an iterator over this list's items.
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()`.
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()`.
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)`.
///
/// This method is equivalent to `self.as_sequence().to_tuple()` and faster than `PyTuple::new(py, this_list)`.
pub fn to_tuple(&self) -> &PyTuple {
Bound::borrowed_from_gil_ref(&self)
.to_tuple()
.into_gil_ref()
self.as_borrowed().to_tuple().into_gil_ref()
}
}

View File

@ -20,13 +20,13 @@ impl PyMapping {
/// This is equivalent to the Python expression `len(self)`.
#[inline]
pub fn len(&self) -> PyResult<usize> {
Bound::borrowed_from_gil_ref(&self).len()
self.as_borrowed().len()
}
/// Returns whether the mapping is empty.
#[inline]
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.
@ -36,7 +36,7 @@ impl PyMapping {
where
K: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).contains(key)
self.as_borrowed().contains(key)
}
/// Gets the item in self with key `key`.
@ -49,9 +49,7 @@ impl PyMapping {
where
K: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self)
.get_item(key)
.map(Bound::into_gil_ref)
self.as_borrowed().get_item(key).map(Bound::into_gil_ref)
}
/// Sets the item in self with key `key`.
@ -63,7 +61,7 @@ impl PyMapping {
K: 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`.
@ -74,31 +72,25 @@ impl PyMapping {
where
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.
#[inline]
pub fn keys(&self) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self)
.keys()
.map(Bound::into_gil_ref)
self.as_borrowed().keys().map(Bound::into_gil_ref)
}
/// Returns a sequence containing all values in the mapping.
#[inline]
pub fn values(&self) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self)
.values()
.map(Bound::into_gil_ref)
self.as_borrowed().values().map(Bound::into_gil_ref)
}
/// Returns a sequence of tuples of all (key, value) pairs in the mapping.
#[inline]
pub fn items(&self) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self)
.items()
.map(Bound::into_gil_ref)
self.as_borrowed().items().map(Bound::into_gil_ref)
}
/// 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())
.and_then(|abc| object.is_instance(abc))
.unwrap_or_else(|err| {
err.write_unraisable_bound(
object.py(),
Some(Bound::borrowed_from_gil_ref(&object)),
);
err.write_unraisable_bound(object.py(), Some(&object.as_borrowed()));
false
})
}

View File

@ -105,9 +105,10 @@ macro_rules! pyobject_native_type_base(
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>)
-> ::std::result::Result<(), ::std::fmt::Error>
{
use $crate::PyNativeType;
match self.str() {
::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() {

View File

@ -1,7 +1,7 @@
use crate::instance::Bound;
use crate::types::any::PyAnyMethods;
use crate::types::PyType;
use crate::{ffi, PyTypeInfo};
use crate::{ffi, PyNativeType, PyTypeInfo};
use crate::{PyAny, PyResult};
/// 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"
)]
pub fn new<'py>(ty: &'py PyType, obj: &'py PyAny) -> PyResult<&'py PySuper> {
Self::new_bound(
Bound::borrowed_from_gil_ref(&ty),
Bound::borrowed_from_gil_ref(&obj),
)
.map(Bound::into_gil_ref)
Self::new_bound(&ty.as_borrowed(), &obj.as_borrowed()).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)
@ -73,7 +69,8 @@ impl PySuper {
ty: &Bound<'py, PyType>,
obj: &Bound<'py, PyAny>,
) -> PyResult<Bound<'py, PySuper>> {
Bound::borrowed_from_gil_ref(&PySuper::type_object(ty.py()))
PySuper::type_object(ty.py())
.as_borrowed()
.call1((ty, obj))
.map(|any| {
// Safety: super() always returns instance of super

View File

@ -23,13 +23,13 @@ impl PySequence {
/// This is equivalent to the Python expression `len(self)`.
#[inline]
pub fn len(&self) -> PyResult<usize> {
Bound::borrowed_from_gil_ref(&self).len()
self.as_borrowed().len()
}
/// Returns whether the sequence is empty.
#[inline]
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`.
@ -37,8 +37,8 @@ impl PySequence {
/// This is equivalent to the Python expression `self + other`.
#[inline]
pub fn concat(&self, other: &PySequence) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self)
.concat(Bound::borrowed_from_gil_ref(&other))
self.as_borrowed()
.concat(&other.as_borrowed())
.map(Bound::into_gil_ref)
}
@ -47,9 +47,7 @@ impl PySequence {
/// This is equivalent to the Python expression `self * count`.
#[inline]
pub fn repeat(&self, count: usize) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self)
.repeat(count)
.map(Bound::into_gil_ref)
self.as_borrowed().repeat(count).map(Bound::into_gil_ref)
}
/// Concatenates `self` and `other`, in place if possible.
@ -61,8 +59,8 @@ impl PySequence {
/// possible, but create and return a new object if not.
#[inline]
pub fn in_place_concat(&self, other: &PySequence) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self)
.in_place_concat(Bound::borrowed_from_gil_ref(&other))
self.as_borrowed()
.in_place_concat(&other.as_borrowed())
.map(Bound::into_gil_ref)
}
@ -75,7 +73,7 @@ impl PySequence {
/// possible, but create and return a new object if not.
#[inline]
pub fn in_place_repeat(&self, count: usize) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self)
self.as_borrowed()
.in_place_repeat(count)
.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.
#[inline]
pub fn get_item(&self, index: usize) -> PyResult<&PyAny> {
Bound::borrowed_from_gil_ref(&self)
.get_item(index)
.map(|py2| py2.into_gil_ref())
self.as_borrowed().get_item(index).map(Bound::into_gil_ref)
}
/// 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]`.
#[inline]
pub fn get_slice(&self, begin: usize, end: usize) -> PyResult<&PySequence> {
Bound::borrowed_from_gil_ref(&self)
self.as_borrowed()
.get_slice(begin, end)
.map(Bound::into_gil_ref)
}
@ -108,7 +104,7 @@ impl PySequence {
where
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.
@ -116,7 +112,7 @@ impl PySequence {
/// This is equivalent to the Python statement `del self[i]`.
#[inline]
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`.
@ -124,7 +120,7 @@ impl PySequence {
/// This is equivalent to the Python statement `self[i1:i2] = v`.
#[inline]
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`.
@ -132,7 +128,7 @@ impl PySequence {
/// This is equivalent to the Python statement `del self[i1:i2]`.
#[inline]
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
@ -143,7 +139,7 @@ impl PySequence {
where
V: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).count(value)
self.as_borrowed().count(value)
}
/// Determines if self contains `value`.
@ -154,7 +150,7 @@ impl PySequence {
where
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`.
@ -165,23 +161,19 @@ impl PySequence {
where
V: ToPyObject,
{
Bound::borrowed_from_gil_ref(&self).index(value)
self.as_borrowed().index(value)
}
/// Returns a fresh list based on the Sequence.
#[inline]
pub fn to_list(&self) -> PyResult<&PyList> {
Bound::borrowed_from_gil_ref(&self)
.to_list()
.map(|py2| py2.into_gil_ref())
self.as_borrowed().to_list().map(Bound::into_gil_ref)
}
/// Returns a fresh tuple based on the Sequence.
#[inline]
pub fn to_tuple(&self) -> PyResult<&PyTuple> {
Bound::borrowed_from_gil_ref(&self)
.to_tuple()
.map(|py2| py2.into_gil_ref())
self.as_borrowed().to_tuple().map(Bound::into_gil_ref)
}
/// 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())
.and_then(|abc| object.is_instance(abc))
.unwrap_or_else(|err| {
err.write_unraisable_bound(
object.py(),
Some(Bound::borrowed_from_gil_ref(&object)),
);
err.write_unraisable_bound(object.py(), Some(&object.as_borrowed()));
false
})
}

View File

@ -5,7 +5,7 @@ use crate::instance::Borrowed;
use crate::types::any::PyAnyMethods;
use crate::types::bytes::PyBytesMethods;
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::os::raw::c_char;
use std::str;
@ -184,7 +184,7 @@ impl PyString {
pub fn to_str(&self) -> PyResult<&str> {
#[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))))]
@ -202,7 +202,7 @@ impl PyString {
/// Returns a `UnicodeEncodeError` if the input is not valid unicode
/// (containing unpaired surrogates).
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.
@ -210,7 +210,7 @@ impl PyString {
/// Unpaired surrogates invalid UTF-8 sequences are
/// replaced with `U+FFFD REPLACEMENT CHARACTER`.
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.
@ -229,7 +229,7 @@ impl PyString {
/// expected on the targets where you plan to distribute your software.
#[cfg(not(Py_LIMITED_API))]
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> {
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
fn to_str(&self) -> PyResult<&str> {
Borrowed::from(self).to_str()
self.as_borrowed().to_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> {
Borrowed::from(self).to_string_lossy()
self.as_borrowed().to_string_lossy()
}
#[cfg(not(Py_LIMITED_API))]
unsafe fn data(&self) -> PyResult<PyStringData<'_>> {
Borrowed::from(self).data()
self.as_borrowed().data()
}
}