Merge pull request #3686 from davidhewitt/bound

make Bound and Borrowed types public API
This commit is contained in:
Adam Reichold 2023-12-21 16:25:01 +00:00 committed by GitHub
commit a115877bba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 576 additions and 572 deletions

View file

@ -0,0 +1 @@
Add `Bound<T>` and `Borrowed<T>` smart pointers as a new API for accessing Python objects.

View file

@ -1,4 +1,4 @@
use crate::instance::Py2;
use crate::instance::Bound;
use crate::panic::PanicException;
use crate::type_object::PyTypeInfo;
use crate::types::any::PyAnyMethods;
@ -65,16 +65,16 @@ impl<'a> PyDowncastError<'a> {
/// Error that indicates a failure to convert a PyAny to a more specific Python type.
#[derive(Debug)]
pub(crate) struct PyDowncastError2<'a, 'py> {
from: &'a Py2<'py, PyAny>,
pub struct DowncastError<'a, 'py> {
from: &'a Bound<'py, PyAny>,
to: Cow<'static, str>,
}
impl<'a, 'py> PyDowncastError2<'a, 'py> {
impl<'a, 'py> DowncastError<'a, 'py> {
/// Create a new `PyDowncastError` representing a failure to convert the object
/// `from` into the type named in `to`.
pub fn new(from: &'a Py2<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
PyDowncastError2 {
pub fn new(from: &'a Bound<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
DowncastError {
from,
to: to.into(),
}
@ -83,16 +83,16 @@ impl<'a, 'py> PyDowncastError2<'a, 'py> {
/// Error that indicates a failure to convert a PyAny to a more specific Python type.
#[derive(Debug)]
pub(crate) struct PyDowncastIntoError<'py> {
from: Py2<'py, PyAny>,
pub struct DowncastIntoError<'py> {
from: Bound<'py, PyAny>,
to: Cow<'static, str>,
}
impl<'py> PyDowncastIntoError<'py> {
/// Create a new `PyDowncastIntoError` representing a failure to convert the object
impl<'py> DowncastIntoError<'py> {
/// Create a new `DowncastIntoError` representing a failure to convert the object
/// `from` into the type named in `to`.
pub fn new(from: Py2<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
PyDowncastIntoError {
pub fn new(from: Bound<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
DowncastIntoError {
from,
to: to.into(),
}
@ -811,13 +811,13 @@ 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, Py2::borrowed_from_gil_ref(&self.from), &self.to)
display_downcast_error(f, Bound::borrowed_from_gil_ref(&self.from), &self.to)
}
}
/// Convert `PyDowncastError2` to Python `TypeError`.
impl std::convert::From<PyDowncastError2<'_, '_>> for PyErr {
fn from(err: PyDowncastError2<'_, '_>) -> PyErr {
/// Convert `DowncastError` to Python `TypeError`.
impl std::convert::From<DowncastError<'_, '_>> for PyErr {
fn from(err: DowncastError<'_, '_>) -> PyErr {
let args = PyDowncastErrorArguments {
from: err.from.get_type().into(),
to: err.to,
@ -827,17 +827,17 @@ impl std::convert::From<PyDowncastError2<'_, '_>> for PyErr {
}
}
impl std::error::Error for PyDowncastError2<'_, '_> {}
impl std::error::Error for DowncastError<'_, '_> {}
impl std::fmt::Display for PyDowncastError2<'_, '_> {
impl std::fmt::Display for DowncastError<'_, '_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
display_downcast_error(f, self.from, &self.to)
}
}
/// Convert `PyDowncastIntoError` to Python `TypeError`.
impl std::convert::From<PyDowncastIntoError<'_>> for PyErr {
fn from(err: PyDowncastIntoError<'_>) -> PyErr {
/// Convert `DowncastIntoError` to Python `TypeError`.
impl std::convert::From<DowncastIntoError<'_>> for PyErr {
fn from(err: DowncastIntoError<'_>) -> PyErr {
let args = PyDowncastErrorArguments {
from: err.from.get_type().into(),
to: err.to,
@ -847,9 +847,9 @@ impl std::convert::From<PyDowncastIntoError<'_>> for PyErr {
}
}
impl std::error::Error for PyDowncastIntoError<'_> {}
impl std::error::Error for DowncastIntoError<'_> {}
impl std::fmt::Display for PyDowncastIntoError<'_> {
impl std::fmt::Display for DowncastIntoError<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
display_downcast_error(f, &self.from, &self.to)
}
@ -857,7 +857,7 @@ impl std::fmt::Display for PyDowncastIntoError<'_> {
fn display_downcast_error(
f: &mut std::fmt::Formatter<'_>,
from: &Py2<'_, PyAny>,
from: &Bound<'_, PyAny>,
to: &str,
) -> std::fmt::Result {
write!(

View file

@ -1,6 +1,6 @@
use crate::{
ffi,
instance::{Py2, Py2Borrowed},
instance::{Borrowed, Bound},
PyAny, PyResult, Python,
};
@ -15,65 +15,57 @@ mod sealed {
use sealed::Sealed;
pub(crate) trait FfiPtrExt: Sealed {
unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult<Py2<'_, PyAny>>;
unsafe fn assume_owned(self, py: Python<'_>) -> Py2<'_, PyAny>;
unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult<Bound<'_, PyAny>>;
unsafe fn assume_owned(self, py: Python<'_>) -> Bound<'_, PyAny>;
/// Assumes this pointer is borrowed from a parent object.
///
/// Warning: the lifetime `'a` is not bounded by the function arguments; the caller is
/// responsible to ensure this is tied to some appropriate lifetime.
unsafe fn assume_borrowed_or_err<'a>(
self,
py: Python<'_>,
) -> PyResult<Py2Borrowed<'a, '_, PyAny>>;
unsafe fn assume_borrowed_or_err<'a>(self, py: Python<'_>)
-> PyResult<Borrowed<'a, '_, PyAny>>;
/// Same as `assume_borrowed_or_err`, but doesn't fetch an error on NULL.
unsafe fn assume_borrowed_or_opt<'a>(
self,
py: Python<'_>,
) -> Option<Py2Borrowed<'a, '_, PyAny>>;
unsafe fn assume_borrowed_or_opt<'a>(self, py: Python<'_>) -> Option<Borrowed<'a, '_, PyAny>>;
/// Same as `assume_borrowed_or_err`, but panics on NULL.
unsafe fn assume_borrowed<'a>(self, py: Python<'_>) -> Py2Borrowed<'a, '_, PyAny>;
unsafe fn assume_borrowed<'a>(self, py: Python<'_>) -> Borrowed<'a, '_, PyAny>;
/// Same as `assume_borrowed_or_err`, but does not check for NULL.
unsafe fn assume_borrowed_unchecked<'a>(self, py: Python<'_>) -> Py2Borrowed<'a, '_, PyAny>;
unsafe fn assume_borrowed_unchecked<'a>(self, py: Python<'_>) -> Borrowed<'a, '_, PyAny>;
}
impl FfiPtrExt for *mut ffi::PyObject {
#[inline]
unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult<Py2<'_, PyAny>> {
Py2::from_owned_ptr_or_err(py, self)
unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
Bound::from_owned_ptr_or_err(py, self)
}
#[inline]
unsafe fn assume_owned(self, py: Python<'_>) -> Py2<'_, PyAny> {
Py2::from_owned_ptr(py, self)
unsafe fn assume_owned(self, py: Python<'_>) -> Bound<'_, PyAny> {
Bound::from_owned_ptr(py, self)
}
#[inline]
unsafe fn assume_borrowed_or_err<'a>(
self,
py: Python<'_>,
) -> PyResult<Py2Borrowed<'a, '_, PyAny>> {
Py2Borrowed::from_ptr_or_err(py, self)
) -> PyResult<Borrowed<'a, '_, PyAny>> {
Borrowed::from_ptr_or_err(py, self)
}
#[inline]
unsafe fn assume_borrowed_or_opt<'a>(
self,
py: Python<'_>,
) -> Option<Py2Borrowed<'a, '_, PyAny>> {
Py2Borrowed::from_ptr_or_opt(py, self)
unsafe fn assume_borrowed_or_opt<'a>(self, py: Python<'_>) -> Option<Borrowed<'a, '_, PyAny>> {
Borrowed::from_ptr_or_opt(py, self)
}
#[inline]
unsafe fn assume_borrowed<'a>(self, py: Python<'_>) -> Py2Borrowed<'a, '_, PyAny> {
Py2Borrowed::from_ptr(py, self)
unsafe fn assume_borrowed<'a>(self, py: Python<'_>) -> Borrowed<'a, '_, PyAny> {
Borrowed::from_ptr(py, self)
}
#[inline]
unsafe fn assume_borrowed_unchecked<'a>(self, py: Python<'_>) -> Py2Borrowed<'a, '_, PyAny> {
Py2Borrowed::from_ptr_unchecked(py, self)
unsafe fn assume_borrowed_unchecked<'a>(self, py: Python<'_>) -> Borrowed<'a, '_, PyAny> {
Borrowed::from_ptr_unchecked(py, self)
}
}

View file

@ -45,22 +45,22 @@ pub unsafe trait PyNativeType: Sized {
/// A GIL-attached equivalent to `Py`.
#[repr(transparent)]
pub(crate) struct Py2<'py, T>(Python<'py>, ManuallyDrop<Py<T>>);
pub struct Bound<'py, T>(Python<'py>, ManuallyDrop<Py<T>>);
impl<'py> Py2<'py, PyAny> {
/// Constructs a new Py2 from a pointer. Panics if ptr is null.
impl<'py> Bound<'py, PyAny> {
/// Constructs a new Bound from a pointer. Panics if ptr is null.
pub(crate) unsafe fn from_owned_ptr(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self {
Self(py, ManuallyDrop::new(Py::from_owned_ptr(py, ptr)))
}
// /// Constructs a new Py2 from a pointer. Returns None if ptr is null.
// /// Constructs a new Bound from a pointer. Returns None if ptr is null.
// ///
// /// Safety: ptr must be a valid pointer to a Python object, or NULL.
// pub unsafe fn from_owned_ptr_or_opt(py: Python<'py>, ptr: *mut ffi::PyObject) -> Option<Self> {
// Py::from_owned_ptr_or_opt(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj)))
// }
/// Constructs a new Py2 from a pointer. Returns error if ptr is null.
/// Constructs a new Bound from a pointer. Returns error if ptr is null.
pub(crate) unsafe fn from_owned_ptr_or_err(
py: Python<'py>,
ptr: *mut ffi::PyObject,
@ -69,22 +69,22 @@ impl<'py> Py2<'py, PyAny> {
}
}
impl<'py, T> Py2<'py, T> {
/// Helper to cast to Py2<'py, PyAny>
pub(crate) fn as_any(&self) -> &Py2<'py, PyAny> {
// Safety: all Py2<T> have the same memory layout, and all Py2<T> are valid Py2<PyAny>
impl<'py, T> Bound<'py, T> {
/// Helper to cast to Bound<'py, PyAny>
pub(crate) fn as_any(&self) -> &Bound<'py, PyAny> {
// Safety: all Bound<T> have the same memory layout, and all Bound<T> are valid Bound<PyAny>
unsafe { std::mem::transmute(self) }
}
}
impl<'py, T> std::fmt::Debug for Py2<'py, T> {
impl<'py, T> std::fmt::Debug for Bound<'py, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
let any = self.as_any();
python_format(any, any.repr(), f)
}
}
impl<'py, T> std::fmt::Display for Py2<'py, T> {
impl<'py, T> std::fmt::Display for Bound<'py, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
let any = self.as_any();
python_format(any, any.str(), f)
@ -92,8 +92,8 @@ impl<'py, T> std::fmt::Display for Py2<'py, T> {
}
fn python_format(
any: &Py2<'_, PyAny>,
format_result: PyResult<Py2<'_, PyString>>,
any: &Bound<'_, PyAny>,
format_result: PyResult<Bound<'_, PyString>>,
f: &mut std::fmt::Formatter<'_>,
) -> Result<(), std::fmt::Error> {
match format_result {
@ -109,40 +109,40 @@ fn python_format(
}
}
impl<'py, T> Deref for Py2<'py, T>
impl<'py, T> Deref for Bound<'py, T>
where
T: AsRef<PyAny>,
{
type Target = Py2<'py, PyAny>;
type Target = Bound<'py, PyAny>;
#[inline]
fn deref(&self) -> &Py2<'py, PyAny> {
fn deref(&self) -> &Bound<'py, PyAny> {
self.as_any()
}
}
impl<'py, T> AsRef<Py2<'py, PyAny>> for Py2<'py, T>
impl<'py, T> AsRef<Bound<'py, PyAny>> for Bound<'py, T>
where
T: AsRef<PyAny>,
{
fn as_ref(&self) -> &Py2<'py, PyAny> {
fn as_ref(&self) -> &Bound<'py, PyAny> {
self.as_any()
}
}
impl<T> Clone for Py2<'_, T> {
impl<T> Clone for Bound<'_, T> {
fn clone(&self) -> Self {
Self(self.0, ManuallyDrop::new(self.1.clone_ref(self.0)))
}
}
impl<T> Drop for Py2<'_, T> {
impl<T> Drop for Bound<'_, T> {
fn drop(&mut self) {
unsafe { ffi::Py_DECREF(self.1.as_ptr()) }
}
}
impl<'py, T> Py2<'py, T> {
impl<'py, T> Bound<'py, T> {
/// Returns the GIL token associated with this object.
pub fn py(&self) -> Python<'py> {
self.0
@ -172,7 +172,7 @@ impl<'py, T> Py2<'py, T> {
self.into_non_null().as_ptr()
}
/// Internal helper to convert e.g. &'a &'py PyDict to &'a Py2<'py, PyDict> for
/// 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
@ -180,7 +180,7 @@ impl<'py, T> Py2<'py, T> {
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 Py2<'py, T>
// so &'a &'py T::AsRefTarget has the same layout as &'a Bound<'py, T>
unsafe { std::mem::transmute(gil_ref) }
}
@ -211,37 +211,33 @@ impl<'py, T> Py2<'py, T> {
}
}
unsafe impl<T> AsPyPointer for Py2<'_, T> {
unsafe impl<T> AsPyPointer for Bound<'_, T> {
fn as_ptr(&self) -> *mut ffi::PyObject {
self.1.as_ptr()
}
}
/// A borrowed equivalent to `Py2`.
/// A borrowed equivalent to `Bound`.
///
/// The advantage of this over `&Py2` is that it avoids the need to have a pointer-to-pointer, as Py2
/// The advantage of this over `&Bound` is that it avoids the need to have a pointer-to-pointer, as Bound
/// is already a pointer to an `ffi::PyObject``.
///
/// Similarly, this type is `Copy` and `Clone`, like a shared reference (`&T`).
#[repr(transparent)]
pub(crate) struct Py2Borrowed<'a, 'py, T>(
NonNull<ffi::PyObject>,
PhantomData<&'a Py<T>>,
Python<'py>,
);
pub struct Borrowed<'a, 'py, T>(NonNull<ffi::PyObject>, PhantomData<&'a Py<T>>, Python<'py>);
impl<'py, T> Py2Borrowed<'_, 'py, T> {
/// Creates a new owned `Py2` from this borrowed reference by increasing the reference count.
pub(crate) fn to_owned(self) -> Py2<'py, T> {
impl<'py, T> Borrowed<'_, 'py, T> {
/// Creates a new owned `Bound` from this borrowed reference by increasing the reference count.
pub(crate) fn to_owned(self) -> Bound<'py, T> {
unsafe { ffi::Py_INCREF(self.as_ptr()) };
Py2(
Bound(
self.py(),
ManuallyDrop::new(unsafe { Py::from_non_null(self.0) }),
)
}
}
impl<'a, 'py> Py2Borrowed<'a, 'py, PyAny> {
impl<'a, 'py> Borrowed<'a, 'py, PyAny> {
/// # Safety
/// This is similar to `std::slice::from_raw_parts`, the lifetime `'a` is completely defined by
/// the caller and it's the caller's responsibility to ensure that the reference this is
@ -285,9 +281,9 @@ impl<'a, 'py> Py2Borrowed<'a, 'py, PyAny> {
}
}
impl<'a, 'py, T> From<&'a Py2<'py, T>> for Py2Borrowed<'a, 'py, T> {
/// Create borrow on a Py2
fn from(instance: &'a Py2<'py, T>) -> Self {
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,
@ -296,7 +292,7 @@ impl<'a, 'py, T> From<&'a Py2<'py, T>> for Py2Borrowed<'a, 'py, T> {
}
}
impl<'py, T> Py2Borrowed<'py, 'py, T>
impl<'py, T> Borrowed<'py, 'py, T>
where
T: HasPyGilRef,
{
@ -312,29 +308,29 @@ where
// }
}
impl<T> std::fmt::Debug for Py2Borrowed<'_, '_, T> {
impl<T> std::fmt::Debug for Borrowed<'_, '_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Py2::fmt(self, f)
Bound::fmt(self, f)
}
}
impl<'py, T> Deref for Py2Borrowed<'_, 'py, T> {
type Target = Py2<'py, T>;
impl<'py, T> Deref for Borrowed<'_, 'py, T> {
type Target = Bound<'py, T>;
#[inline]
fn deref(&self) -> &Py2<'py, T> {
// safety: Py2 has the same layout as NonNull<ffi::PyObject>
unsafe { &*(&self.0 as *const _ as *const Py2<'py, T>) }
fn deref(&self) -> &Bound<'py, T> {
// safety: Bound has the same layout as NonNull<ffi::PyObject>
unsafe { &*(&self.0 as *const _ as *const Bound<'py, T>) }
}
}
impl<T> Clone for Py2Borrowed<'_, '_, T> {
impl<T> Clone for Borrowed<'_, '_, T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for Py2Borrowed<'_, '_, T> {}
impl<T> Copy for Borrowed<'_, '_, T> {}
/// A GIL-independent reference to an object allocated on the Python heap.
///
@ -836,18 +832,19 @@ where
impl<T> Py<T> {
/// Attaches this `Py` to the given Python context, allowing access to further Python APIs.
pub(crate) fn attach<'py>(&self, _py: Python<'py>) -> &Py2<'py, T> {
// Safety: `Py2` has the same layout as `Py`
pub fn bind<'py>(&self, _py: Python<'py>) -> &Bound<'py, T> {
// Safety: `Bound` has the same layout as `Py`
unsafe { &*(self as *const Py<T>).cast() }
}
/// Same as `attach` but takes ownership of `self`.
pub(crate) fn attach_into(self, py: Python<'_>) -> Py2<'_, T> {
Py2(py, ManuallyDrop::new(self))
/// Same as `bind` but takes ownership of `self`.
pub fn into_bound(self, py: Python<'_>) -> Bound<'_, T> {
Bound(py, ManuallyDrop::new(self))
}
pub(crate) fn attach_borrow<'a, 'py>(&'a self, py: Python<'py>) -> Py2Borrowed<'a, 'py, T> {
Py2Borrowed(self.0, PhantomData, py)
/// Same as `bind` but produces a `Borrowed<T>` instead of a `Bound<T>`.
pub fn bind_borrowed<'a, 'py>(&'a self, py: Python<'py>) -> Borrowed<'a, 'py, T> {
Borrowed(self.0, PhantomData, py)
}
/// Returns whether `self` and `other` point to the same object. To compare
@ -961,7 +958,7 @@ impl<T> Py<T> {
where
N: IntoPy<Py<PyString>>,
{
self.attach(py).as_any().getattr(attr_name).map(Into::into)
self.bind(py).as_any().getattr(attr_name).map(Into::into)
}
/// Sets an attribute value.
@ -991,9 +988,9 @@ impl<T> Py<T> {
N: IntoPy<Py<PyString>>,
V: IntoPy<Py<PyAny>>,
{
self.attach(py)
self.bind(py)
.as_any()
.setattr(attr_name, value.into_py(py).attach_into(py))
.setattr(attr_name, value.into_py(py).into_bound(py))
}
/// Calls the object.
@ -1005,21 +1002,21 @@ impl<T> Py<T> {
args: impl IntoPy<Py<PyTuple>>,
kwargs: Option<&PyDict>,
) -> PyResult<PyObject> {
self.attach(py).as_any().call(args, kwargs).map(Into::into)
self.bind(py).as_any().call(args, kwargs).map(Into::into)
}
/// Calls the object with only positional arguments.
///
/// This is equivalent to the Python expression `self(*args)`.
pub fn call1(&self, py: Python<'_>, args: impl IntoPy<Py<PyTuple>>) -> PyResult<PyObject> {
self.attach(py).as_any().call1(args).map(Into::into)
self.bind(py).as_any().call1(args).map(Into::into)
}
/// Calls the object without arguments.
///
/// This is equivalent to the Python expression `self()`.
pub fn call0(&self, py: Python<'_>) -> PyResult<PyObject> {
self.attach(py).as_any().call0().map(Into::into)
self.bind(py).as_any().call0().map(Into::into)
}
/// Calls a method on the object.
@ -1039,7 +1036,7 @@ impl<T> Py<T> {
N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>,
{
self.attach(py)
self.bind(py)
.as_any()
.call_method(name, args, kwargs)
.map(Into::into)
@ -1056,7 +1053,7 @@ impl<T> Py<T> {
N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>,
{
self.attach(py)
self.bind(py)
.as_any()
.call_method1(name, args)
.map(Into::into)
@ -1072,7 +1069,7 @@ impl<T> Py<T> {
where
N: IntoPy<Py<PyString>>,
{
self.attach(py).as_any().call_method0(name).map(Into::into)
self.bind(py).as_any().call_method0(name).map(Into::into)
}
/// Create a `Py<T>` instance by taking ownership of the given FFI pointer.
@ -1208,14 +1205,14 @@ impl<T> IntoPy<PyObject> for &'_ Py<T> {
}
}
impl<T> ToPyObject for Py2<'_, T> {
impl<T> ToPyObject for Bound<'_, T> {
/// Converts `Py` instance -> PyObject.
fn to_object(&self, py: Python<'_>) -> PyObject {
unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) }
}
}
impl<T> IntoPy<PyObject> for Py2<'_, T> {
impl<T> IntoPy<PyObject> for Bound<'_, T> {
/// Converts a `Py` instance to `PyObject`.
/// Consumes `self` without calling `Py_DECREF()`.
#[inline]
@ -1224,7 +1221,7 @@ impl<T> IntoPy<PyObject> for Py2<'_, T> {
}
}
impl<T> IntoPy<PyObject> for &Py2<'_, T> {
impl<T> IntoPy<PyObject> for &Bound<'_, T> {
/// Converts a `Py` instance to `PyObject`.
/// Consumes `self` without calling `Py_DECREF()`.
#[inline]
@ -1266,20 +1263,20 @@ where
}
}
impl<T> std::convert::From<Py2<'_, T>> for PyObject
impl<T> std::convert::From<Bound<'_, T>> for PyObject
where
T: AsRef<PyAny>,
{
#[inline]
fn from(other: Py2<'_, T>) -> Self {
fn from(other: Bound<'_, T>) -> Self {
let py = other.py();
other.into_py(py)
}
}
impl<T> std::convert::From<Py2<'_, T>> for Py<T> {
impl<T> std::convert::From<Bound<'_, T>> for Py<T> {
#[inline]
fn from(other: Py2<'_, T>) -> Self {
fn from(other: Bound<'_, T>) -> Self {
unsafe { Self::from_non_null(other.into_non_null()) }
}
}
@ -1348,13 +1345,13 @@ where
}
}
impl<'a, T> FromPyObject<'a> for Py2<'a, T>
impl<'a, T> FromPyObject<'a> for Bound<'a, T>
where
T: PyTypeInfo,
{
/// Extracts `Self` from the source `PyObject`.
fn extract(ob: &'a PyAny) -> PyResult<Self> {
Py2::borrowed_from_gil_ref(&ob)
Bound::borrowed_from_gil_ref(&ob)
.downcast()
.map(Clone::clone)
.map_err(Into::into)
@ -1471,7 +1468,7 @@ impl PyObject {
#[cfg(test)]
mod tests {
use super::{Py, Py2, PyObject};
use super::{Bound, Py, PyObject};
use crate::types::{PyDict, PyString};
use crate::{PyAny, PyResult, Python, ToPyObject};
@ -1592,7 +1589,7 @@ a = A()
Python::with_gil(|py| {
let instance: &PyAny = py.eval("object()", None, None).unwrap();
let ptr = instance.as_ptr();
let instance: Py2<'_, PyAny> = instance.extract().unwrap();
let instance: Bound<'_, PyAny> = instance.extract().unwrap();
assert_eq!(instance.as_ptr(), ptr);
})
}
@ -1600,8 +1597,8 @@ a = A()
#[test]
fn test_py2_into_py_object() {
Python::with_gil(|py| {
let instance: Py2<'_, PyAny> =
Py2::borrowed_from_gil_ref(&py.eval("object()", None, None).unwrap()).clone();
let instance: Bound<'_, PyAny> =
Bound::borrowed_from_gil_ref(&py.eval("object()", None, None).unwrap()).clone();
let ptr = instance.as_ptr();
let instance: PyObject = instance.clone().into();
assert_eq!(instance.as_ptr(), ptr);
@ -1628,7 +1625,7 @@ a = A()
#[test]
fn test_debug_fmt() {
Python::with_gil(|py| {
let obj = "hello world".to_object(py).attach_into(py);
let obj = "hello world".to_object(py).into_bound(py);
assert_eq!(format!("{:?}", obj), "'hello world'");
});
}
@ -1636,7 +1633,7 @@ a = A()
#[test]
fn test_display_fmt() {
Python::with_gil(|py| {
let obj = "hello world".to_object(py).attach_into(py);
let obj = "hello world".to_object(py).into_bound(py);
assert_eq!(format!("{}", obj), "hello world");
});
}

View file

@ -297,7 +297,9 @@ pub use crate::class::*;
pub use crate::conversion::{AsPyPointer, FromPyObject, FromPyPointer, IntoPy, ToPyObject};
#[allow(deprecated)]
pub use crate::conversion::{PyTryFrom, PyTryInto};
pub use crate::err::{PyDowncastError, PyErr, PyErrArguments, PyResult};
pub use crate::err::{
DowncastError, DowncastIntoError, PyDowncastError, PyErr, PyErrArguments, PyResult,
};
pub use crate::gil::GILPool;
#[cfg(not(PyPy))]
pub use crate::gil::{prepare_freethreaded_python, with_embedded_python_interpreter};
@ -311,7 +313,7 @@ pub use crate::types::PyAny;
pub use crate::version::PythonVersionInfo;
// Expected to become public API in 0.21 under a different name
pub(crate) use crate::instance::Py2;
pub(crate) use crate::instance::Bound;
pub(crate) mod ffi_ptr_ext;
pub(crate) mod py_result_ext;

View file

@ -12,7 +12,7 @@ pub use crate::conversion::{FromPyObject, IntoPy, ToPyObject};
#[allow(deprecated)]
pub use crate::conversion::{PyTryFrom, PyTryInto};
pub use crate::err::{PyErr, PyResult};
pub use crate::instance::{Py, PyObject};
pub use crate::instance::{Borrowed, Bound, Py, PyObject};
pub use crate::marker::Python;
pub use crate::pycell::{PyCell, PyRef, PyRefMut};
pub use crate::pyclass_init::PyClassInitializer;
@ -24,15 +24,13 @@ pub use pyo3_macros::{pyclass, pyfunction, pymethods, pymodule, FromPyObject};
#[cfg(feature = "macros")]
pub use crate::wrap_pyfunction;
// Expected to become public API in 0.21
// pub(crate) use crate::instance::Py2; // Will be stabilized with a different name
// pub(crate) use crate::types::any::PyAnyMethods;
// pub(crate) use crate::types::boolobject::PyBoolMethods;
// pub(crate) use crate::types::bytearray::PyByteArrayMethods;
// pub(crate) use crate::types::bytes::PyBytesMethods;
// pub(crate) use crate::types::dict::PyDictMethods;
// pub(crate) use crate::types::float::PyFloatMethods;
// pub(crate) use crate::types::list::PyListMethods;
// pub(crate) use crate::types::mapping::PyMappingMethods;
// pub(crate) use crate::types::sequence::PySequenceMethods;
// pub(crate) use crate::types::string::PyStringMethods;
pub use crate::types::any::PyAnyMethods;
pub use crate::types::boolobject::PyBoolMethods;
pub use crate::types::bytearray::PyByteArrayMethods;
pub use crate::types::bytes::PyBytesMethods;
pub use crate::types::dict::PyDictMethods;
pub use crate::types::float::PyFloatMethods;
pub use crate::types::list::PyListMethods;
pub use crate::types::mapping::PyMappingMethods;
pub use crate::types::sequence::PySequenceMethods;
pub use crate::types::string::PyStringMethods;

View file

@ -1,22 +1,22 @@
use crate::{types::any::PyAnyMethods, Py2, PyAny, PyResult};
use crate::{types::any::PyAnyMethods, Bound, PyAny, PyResult};
mod sealed {
use super::*;
pub trait Sealed {}
impl Sealed for PyResult<Py2<'_, PyAny>> {}
impl Sealed for PyResult<Bound<'_, PyAny>> {}
}
use sealed::Sealed;
pub(crate) trait PyResultExt<'py>: Sealed {
unsafe fn downcast_into_unchecked<T>(self) -> PyResult<Py2<'py, T>>;
unsafe fn downcast_into_unchecked<T>(self) -> PyResult<Bound<'py, T>>;
}
impl<'py> PyResultExt<'py> for PyResult<Py2<'py, PyAny>> {
impl<'py> PyResultExt<'py> for PyResult<Bound<'py, PyAny>> {
#[inline]
unsafe fn downcast_into_unchecked<T>(self) -> PyResult<Py2<'py, T>> {
unsafe fn downcast_into_unchecked<T>(self) -> PyResult<Bound<'py, T>> {
self.map(|instance| instance.downcast_into_unchecked())
}
}

View file

@ -1,9 +1,9 @@
use crate::class::basic::CompareOp;
use crate::conversion::{AsPyPointer, FromPyObject, IntoPy, ToPyObject};
use crate::err::{PyDowncastError, PyDowncastError2, PyDowncastIntoError, PyErr, PyResult};
use crate::err::{DowncastError, DowncastIntoError, PyDowncastError, PyErr, PyResult};
use crate::exceptions::{PyAttributeError, PyTypeError};
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::Py2;
use crate::instance::Bound;
use crate::py_result_ext::PyResultExt;
use crate::type_object::{HasPyGilRef, PyTypeCheck, PyTypeInfo};
#[cfg(not(PyPy))]
@ -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 {
Py2::borrowed_from_gil_ref(&self).is(other)
Bound::borrowed_from_gil_ref(&self).is(other)
}
/// Determines whether this object has the given attribute.
@ -102,7 +102,7 @@ impl PyAny {
where
N: IntoPy<Py<PyString>>,
{
Py2::borrowed_from_gil_ref(&self).hasattr(attr_name)
Bound::borrowed_from_gil_ref(&self).hasattr(attr_name)
}
/// Retrieves an attribute value.
@ -131,9 +131,9 @@ impl PyAny {
where
N: IntoPy<Py<PyString>>,
{
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.getattr(attr_name)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Retrieve an attribute value, skipping the instance dictionary during the lookup but still
@ -208,7 +208,7 @@ impl PyAny {
N: IntoPy<Py<PyString>>,
V: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).setattr(attr_name, value)
Bound::borrowed_from_gil_ref(&self).setattr(attr_name, value)
}
/// Deletes an attribute.
@ -221,7 +221,7 @@ impl PyAny {
where
N: IntoPy<Py<PyString>>,
{
Py2::borrowed_from_gil_ref(&self).delattr(attr_name)
Bound::borrowed_from_gil_ref(&self).delattr(attr_name)
}
/// Returns an [`Ordering`] between `self` and `other`.
@ -274,7 +274,7 @@ impl PyAny {
where
O: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).compare(other)
Bound::borrowed_from_gil_ref(&self).compare(other)
}
/// Tests whether two Python objects obey a given [`CompareOp`].
@ -315,9 +315,9 @@ impl PyAny {
where
O: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.rich_compare(other, compare_op)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Tests whether this object is less than another.
@ -327,7 +327,7 @@ impl PyAny {
where
O: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).lt(other)
Bound::borrowed_from_gil_ref(&self).lt(other)
}
/// Tests whether this object is less than or equal to another.
@ -337,7 +337,7 @@ impl PyAny {
where
O: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).le(other)
Bound::borrowed_from_gil_ref(&self).le(other)
}
/// Tests whether this object is equal to another.
@ -347,7 +347,7 @@ impl PyAny {
where
O: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).eq(other)
Bound::borrowed_from_gil_ref(&self).eq(other)
}
/// Tests whether this object is not equal to another.
@ -357,7 +357,7 @@ impl PyAny {
where
O: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).ne(other)
Bound::borrowed_from_gil_ref(&self).ne(other)
}
/// Tests whether this object is greater than another.
@ -367,7 +367,7 @@ impl PyAny {
where
O: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).gt(other)
Bound::borrowed_from_gil_ref(&self).gt(other)
}
/// Tests whether this object is greater than or equal to another.
@ -377,7 +377,7 @@ impl PyAny {
where
O: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).ge(other)
Bound::borrowed_from_gil_ref(&self).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 {
Py2::borrowed_from_gil_ref(&self).is_callable()
Bound::borrowed_from_gil_ref(&self).is_callable()
}
/// Calls the object.
@ -446,9 +446,9 @@ impl PyAny {
args: impl IntoPy<Py<PyTuple>>,
kwargs: Option<&PyDict>,
) -> PyResult<&PyAny> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.call(args, kwargs)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Calls the object without arguments.
@ -472,9 +472,9 @@ impl PyAny {
///
/// This is equivalent to the Python expression `help()`.
pub fn call0(&self) -> PyResult<&PyAny> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.call0()
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Calls the object with only positional arguments.
@ -505,9 +505,9 @@ impl PyAny {
/// # }
/// ```
pub fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyAny> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.call1(args)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Calls a method on the object.
@ -550,9 +550,9 @@ impl PyAny {
N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>,
{
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.call_method(name, args, kwargs)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Calls a method on the object without arguments.
@ -590,9 +590,9 @@ impl PyAny {
where
N: IntoPy<Py<PyString>>,
{
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.call_method0(name)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Calls a method on the object with only positional arguments.
@ -632,9 +632,9 @@ impl PyAny {
N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>,
{
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.call_method1(name, args)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Returns whether the object is considered to be true.
@ -649,7 +649,7 @@ impl PyAny {
///
/// This applies truth value testing equivalent to the Python expression `bool(self)`.
pub fn is_truthy(&self) -> PyResult<bool> {
Py2::borrowed_from_gil_ref(&self).is_truthy()
Bound::borrowed_from_gil_ref(&self).is_truthy()
}
/// Returns whether the object is considered to be None.
@ -657,7 +657,7 @@ impl PyAny {
/// This is equivalent to the Python expression `self is None`.
#[inline]
pub fn is_none(&self) -> bool {
Py2::borrowed_from_gil_ref(&self).is_none()
Bound::borrowed_from_gil_ref(&self).is_none()
}
/// Returns whether the object is Ellipsis, e.g. `...`.
@ -665,14 +665,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 {
Py2::borrowed_from_gil_ref(&self).is_ellipsis()
Bound::borrowed_from_gil_ref(&self).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> {
Py2::borrowed_from_gil_ref(&self).is_empty()
Bound::borrowed_from_gil_ref(&self).is_empty()
}
/// Gets an item from the collection.
@ -682,9 +682,9 @@ impl PyAny {
where
K: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.get_item(key)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Sets a collection item value.
@ -695,7 +695,7 @@ impl PyAny {
K: ToPyObject,
V: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).set_item(key, value)
Bound::borrowed_from_gil_ref(&self).set_item(key, value)
}
/// Deletes an item from the collection.
@ -705,7 +705,7 @@ impl PyAny {
where
K: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).del_item(key)
Bound::borrowed_from_gil_ref(&self).del_item(key)
}
/// Takes an object and returns an iterator for it.
@ -713,20 +713,20 @@ impl PyAny {
/// This is typically a new iterator but if the argument is an iterator,
/// this returns itself.
pub fn iter(&self) -> PyResult<&PyIterator> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.iter()
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Returns the Python type object for this object's type.
pub fn get_type(&self) -> &PyType {
Py2::borrowed_from_gil_ref(&self).get_type()
Bound::borrowed_from_gil_ref(&self).get_type()
}
/// Returns the Python type pointer for this object.
#[inline]
pub fn get_type_ptr(&self) -> *mut ffi::PyTypeObject {
Py2::borrowed_from_gil_ref(&self).get_type_ptr()
Bound::borrowed_from_gil_ref(&self).get_type_ptr()
}
/// Downcast this `PyAny` to a concrete Python type or pyclass.
@ -863,46 +863,46 @@ impl PyAny {
/// Returns the reference count for the Python object.
pub fn get_refcnt(&self) -> isize {
Py2::borrowed_from_gil_ref(&self).get_refcnt()
Bound::borrowed_from_gil_ref(&self).get_refcnt()
}
/// Computes the "repr" representation of self.
///
/// This is equivalent to the Python expression `repr(self)`.
pub fn repr(&self) -> PyResult<&PyString> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.repr()
.map(Py2::into_gil_ref)
.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> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.str()
.map(Py2::into_gil_ref)
.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> {
Py2::borrowed_from_gil_ref(&self).hash()
Bound::borrowed_from_gil_ref(&self).hash()
}
/// Returns the length of the sequence or mapping.
///
/// This is equivalent to the Python expression `len(self)`.
pub fn len(&self) -> PyResult<usize> {
Py2::borrowed_from_gil_ref(&self).len()
Bound::borrowed_from_gil_ref(&self).len()
}
/// Returns the list of attributes of this object.
///
/// This is equivalent to the Python expression `dir(self)`.
pub fn dir(&self) -> &PyList {
Py2::borrowed_from_gil_ref(&self).dir().into_gil_ref()
Bound::borrowed_from_gil_ref(&self).dir().into_gil_ref()
}
/// Checks whether this object is an instance of type `ty`.
@ -910,7 +910,7 @@ impl PyAny {
/// This is equivalent to the Python expression `isinstance(self, ty)`.
#[inline]
pub fn is_instance(&self, ty: &PyAny) -> PyResult<bool> {
Py2::borrowed_from_gil_ref(&self).is_instance(Py2::borrowed_from_gil_ref(&ty))
Bound::borrowed_from_gil_ref(&self).is_instance(Bound::borrowed_from_gil_ref(&ty))
}
/// Checks whether this object is an instance of exactly type `ty` (not a subclass).
@ -918,7 +918,7 @@ impl PyAny {
/// This is equivalent to the Python expression `type(self) is ty`.
#[inline]
pub fn is_exact_instance(&self, ty: &PyAny) -> bool {
Py2::borrowed_from_gil_ref(&self).is_exact_instance(Py2::borrowed_from_gil_ref(&ty))
Bound::borrowed_from_gil_ref(&self).is_exact_instance(Bound::borrowed_from_gil_ref(&ty))
}
/// Checks whether this object is an instance of type `T`.
@ -927,7 +927,7 @@ impl PyAny {
/// if the type `T` is known at compile time.
#[inline]
pub fn is_instance_of<T: PyTypeInfo>(&self) -> bool {
Py2::borrowed_from_gil_ref(&self).is_instance_of::<T>()
Bound::borrowed_from_gil_ref(&self).is_instance_of::<T>()
}
/// Checks whether this object is an instance of exactly type `T`.
@ -936,7 +936,7 @@ impl PyAny {
/// if the type `T` is known at compile time.
#[inline]
pub fn is_exact_instance_of<T: PyTypeInfo>(&self) -> bool {
Py2::borrowed_from_gil_ref(&self).is_exact_instance_of::<T>()
Bound::borrowed_from_gil_ref(&self).is_exact_instance_of::<T>()
}
/// Determines if self contains `value`.
@ -946,7 +946,7 @@ impl PyAny {
where
V: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).contains(value)
Bound::borrowed_from_gil_ref(&self).contains(value)
}
/// Returns a GIL marker constrained to the lifetime of this type.
@ -985,9 +985,9 @@ impl PyAny {
/// This is equivalent to the Python expression `super()`
#[cfg(not(PyPy))]
pub fn py_super(&self) -> PyResult<&PySuper> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.py_super()
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
}
@ -996,7 +996,7 @@ impl PyAny {
/// It is recommended you import this trait via `use pyo3::prelude::*` rather than
/// by importing this trait directly.
#[doc(alias = "PyAny")]
pub(crate) trait PyAnyMethods<'py> {
pub trait PyAnyMethods<'py> {
/// Returns whether `self` and `other` point to the same object. To compare
/// the equality of two objects (the `==` operator), use [`eq`](PyAny::eq).
///
@ -1051,7 +1051,7 @@ pub(crate) trait PyAnyMethods<'py> {
/// # version(sys).unwrap();
/// # });
/// ```
fn getattr<N>(&self, attr_name: N) -> PyResult<Py2<'py, PyAny>>
fn getattr<N>(&self, attr_name: N) -> PyResult<Bound<'py, PyAny>>
where
N: IntoPy<Py<PyString>>;
@ -1176,7 +1176,7 @@ pub(crate) trait PyAnyMethods<'py> {
/// })?;
/// # Ok(())}
/// ```
fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<Py2<'py, PyAny>>
fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<Bound<'py, PyAny>>
where
O: ToPyObject;
@ -1285,7 +1285,7 @@ pub(crate) trait PyAnyMethods<'py> {
&self,
args: impl IntoPy<Py<PyTuple>>,
kwargs: Option<&PyDict>,
) -> PyResult<Py2<'py, PyAny>>;
) -> PyResult<Bound<'py, PyAny>>;
/// Calls the object without arguments.
///
@ -1307,7 +1307,7 @@ pub(crate) trait PyAnyMethods<'py> {
/// ```
///
/// This is equivalent to the Python expression `help()`.
fn call0(&self) -> PyResult<Py2<'py, PyAny>>;
fn call0(&self) -> PyResult<Bound<'py, PyAny>>;
/// Calls the object with only positional arguments.
///
@ -1336,7 +1336,7 @@ pub(crate) trait PyAnyMethods<'py> {
/// })
/// # }
/// ```
fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<Py2<'py, PyAny>>;
fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<Bound<'py, PyAny>>;
/// Calls a method on the object.
///
@ -1378,7 +1378,7 @@ pub(crate) trait PyAnyMethods<'py> {
name: N,
args: A,
kwargs: Option<&PyDict>,
) -> PyResult<Py2<'py, PyAny>>
) -> PyResult<Bound<'py, PyAny>>
where
N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>;
@ -1414,7 +1414,7 @@ pub(crate) trait PyAnyMethods<'py> {
/// })
/// # }
/// ```
fn call_method0<N>(&self, name: N) -> PyResult<Py2<'py, PyAny>>
fn call_method0<N>(&self, name: N) -> PyResult<Bound<'py, PyAny>>
where
N: IntoPy<Py<PyString>>;
@ -1450,7 +1450,7 @@ pub(crate) trait PyAnyMethods<'py> {
/// })
/// # }
/// ```
fn call_method1<N, A>(&self, name: N, args: A) -> PyResult<Py2<'py, PyAny>>
fn call_method1<N, A>(&self, name: N, args: A) -> PyResult<Bound<'py, PyAny>>
where
N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>;
@ -1478,7 +1478,7 @@ pub(crate) trait PyAnyMethods<'py> {
/// Gets an item from the collection.
///
/// This is equivalent to the Python expression `self[key]`.
fn get_item<K>(&self, key: K) -> PyResult<Py2<'py, PyAny>>
fn get_item<K>(&self, key: K) -> PyResult<Bound<'py, PyAny>>
where
K: ToPyObject;
@ -1501,7 +1501,7 @@ pub(crate) trait PyAnyMethods<'py> {
///
/// This is typically a new iterator but if the argument is an iterator,
/// this returns itself.
fn iter(&self) -> PyResult<Py2<'py, PyIterator>>;
fn iter(&self) -> PyResult<Bound<'py, PyIterator>>;
/// Returns the Python type object for this object's type.
fn get_type(&self) -> &'py PyType;
@ -1561,12 +1561,12 @@ pub(crate) trait PyAnyMethods<'py> {
/// })
/// # }
/// ```
fn downcast<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError2<'_, 'py>>
fn downcast<T>(&self) -> Result<&Bound<'py, T>, DowncastError<'_, 'py>>
where
T: PyTypeCheck;
/// Like `downcast` but takes ownership of `self`.
fn downcast_into<T>(self) -> Result<Py2<'py, T>, PyDowncastIntoError<'py>>
fn downcast_into<T>(self) -> Result<Bound<'py, T>, DowncastIntoError<'py>>
where
T: PyTypeCheck;
@ -1600,12 +1600,12 @@ pub(crate) trait PyAnyMethods<'py> {
/// assert!(any.downcast_exact::<PyBool>().is_ok());
/// });
/// ```
fn downcast_exact<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError2<'_, 'py>>
fn downcast_exact<T>(&self) -> Result<&Bound<'py, T>, DowncastError<'_, 'py>>
where
T: PyTypeInfo;
/// Like `downcast_exact` but takes ownership of `self`.
fn downcast_into_exact<T>(self) -> Result<Py2<'py, T>, PyDowncastIntoError<'py>>
fn downcast_into_exact<T>(self) -> Result<Bound<'py, T>, DowncastIntoError<'py>>
where
T: PyTypeInfo;
@ -1614,10 +1614,14 @@ pub(crate) trait PyAnyMethods<'py> {
/// # Safety
///
/// Callers must ensure that the type is valid or risk type confusion.
unsafe fn downcast_unchecked<T>(&self) -> &Py2<'py, T>;
unsafe fn downcast_unchecked<T>(&self) -> &Bound<'py, T>;
/// Like `downcast_unchecked` but takes ownership of `self`.
unsafe fn downcast_into_unchecked<T>(self) -> Py2<'py, T>;
///
/// # Safety
///
/// Callers must ensure that the type is valid or risk type confusion.
unsafe fn downcast_into_unchecked<T>(self) -> Bound<'py, T>;
/// Extracts some type from the Python object.
///
@ -1632,12 +1636,12 @@ pub(crate) trait PyAnyMethods<'py> {
/// Computes the "repr" representation of self.
///
/// This is equivalent to the Python expression `repr(self)`.
fn repr(&self) -> PyResult<Py2<'py, PyString>>;
fn repr(&self) -> PyResult<Bound<'py, PyString>>;
/// Computes the "str" representation of self.
///
/// This is equivalent to the Python expression `str(self)`.
fn str(&self) -> PyResult<Py2<'py, PyString>>;
fn str(&self) -> PyResult<Bound<'py, PyString>>;
/// Retrieves the hash code of self.
///
@ -1652,17 +1656,17 @@ pub(crate) trait PyAnyMethods<'py> {
/// Returns the list of attributes of this object.
///
/// This is equivalent to the Python expression `dir(self)`.
fn dir(&self) -> Py2<'py, PyList>;
fn dir(&self) -> Bound<'py, PyList>;
/// Checks whether this object is an instance of type `ty`.
///
/// This is equivalent to the Python expression `isinstance(self, ty)`.
fn is_instance(&self, ty: &Py2<'py, PyAny>) -> PyResult<bool>;
fn is_instance(&self, ty: &Bound<'py, PyAny>) -> PyResult<bool>;
/// Checks whether this object is an instance of exactly type `ty` (not a subclass).
///
/// This is equivalent to the Python expression `type(self) is ty`.
fn is_exact_instance(&self, ty: &Py2<'py, PyAny>) -> bool;
fn is_exact_instance(&self, ty: &Bound<'py, PyAny>) -> bool;
/// Checks whether this object is an instance of type `T`.
///
@ -1687,10 +1691,10 @@ pub(crate) trait PyAnyMethods<'py> {
///
/// This is equivalent to the Python expression `super()`
#[cfg(not(PyPy))]
fn py_super(&self) -> PyResult<Py2<'py, PySuper>>;
fn py_super(&self) -> PyResult<Bound<'py, PySuper>>;
}
impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
#[inline]
fn is<T: AsPyPointer>(&self, other: &T) -> bool {
self.as_ptr() == other.as_ptr()
@ -1702,7 +1706,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
{
// PyObject_HasAttr suppresses all exceptions, which was the behaviour of `hasattr` in Python 2.
// Use an implementation which suppresses only AttributeError, which is consistent with `hasattr` in Python 3.
fn inner(py: Python<'_>, getattr_result: PyResult<Py2<'_, PyAny>>) -> PyResult<bool> {
fn inner(py: Python<'_>, getattr_result: PyResult<Bound<'_, PyAny>>) -> PyResult<bool> {
match getattr_result {
Ok(_) => Ok(true),
Err(err) if err.is_instance_of::<PyAttributeError>(py) => Ok(false),
@ -1713,14 +1717,14 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
inner(self.py(), self.getattr(attr_name))
}
fn getattr<N>(&self, attr_name: N) -> PyResult<Py2<'py, PyAny>>
fn getattr<N>(&self, attr_name: N) -> PyResult<Bound<'py, PyAny>>
where
N: IntoPy<Py<PyString>>,
{
fn inner<'py>(
any: &Py2<'py, PyAny>,
attr_name: Py2<'_, PyString>,
) -> PyResult<Py2<'py, PyAny>> {
any: &Bound<'py, PyAny>,
attr_name: Bound<'_, PyString>,
) -> PyResult<Bound<'py, PyAny>> {
unsafe {
ffi::PyObject_GetAttr(any.as_ptr(), attr_name.as_ptr())
.assume_owned_or_err(any.py())
@ -1728,7 +1732,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
}
let py = self.py();
inner(self, attr_name.into_py(self.py()).attach_into(py))
inner(self, attr_name.into_py(self.py()).into_bound(py))
}
fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()>
@ -1737,9 +1741,9 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
V: ToPyObject,
{
fn inner(
any: &Py2<'_, PyAny>,
attr_name: Py2<'_, PyString>,
value: Py2<'_, PyAny>,
any: &Bound<'_, PyAny>,
attr_name: Bound<'_, PyString>,
value: Bound<'_, PyAny>,
) -> PyResult<()> {
err::error_on_minusone(any.py(), unsafe {
ffi::PyObject_SetAttr(any.as_ptr(), attr_name.as_ptr(), value.as_ptr())
@ -1749,8 +1753,8 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
let py = self.py();
inner(
self,
attr_name.into_py(py).attach_into(py),
value.to_object(py).attach_into(py),
attr_name.into_py(py).into_bound(py),
value.to_object(py).into_bound(py),
)
}
@ -1758,21 +1762,21 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
where
N: IntoPy<Py<PyString>>,
{
fn inner(any: &Py2<'_, PyAny>, attr_name: Py2<'_, PyString>) -> PyResult<()> {
fn inner(any: &Bound<'_, PyAny>, attr_name: Bound<'_, PyString>) -> PyResult<()> {
err::error_on_minusone(any.py(), unsafe {
ffi::PyObject_DelAttr(any.as_ptr(), attr_name.as_ptr())
})
}
let py = self.py();
inner(self, attr_name.into_py(py).attach_into(py))
inner(self, attr_name.into_py(py).into_bound(py))
}
fn compare<O>(&self, other: O) -> PyResult<Ordering>
where
O: ToPyObject,
{
fn inner(any: &Py2<'_, PyAny>, other: Py2<'_, PyAny>) -> PyResult<Ordering> {
fn inner(any: &Bound<'_, PyAny>, other: Bound<'_, PyAny>) -> PyResult<Ordering> {
let other = other.as_ptr();
// Almost the same as ffi::PyObject_RichCompareBool, but this one doesn't try self == other.
// See https://github.com/PyO3/pyo3/issues/985 for more.
@ -1795,18 +1799,18 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
}
let py = self.py();
inner(self, other.to_object(py).attach_into(py))
inner(self, other.to_object(py).into_bound(py))
}
fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<Py2<'py, PyAny>>
fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<Bound<'py, PyAny>>
where
O: ToPyObject,
{
fn inner<'py>(
any: &Py2<'py, PyAny>,
other: Py2<'_, PyAny>,
any: &Bound<'py, PyAny>,
other: Bound<'_, PyAny>,
compare_op: CompareOp,
) -> PyResult<Py2<'py, PyAny>> {
) -> PyResult<Bound<'py, PyAny>> {
unsafe {
ffi::PyObject_RichCompare(any.as_ptr(), other.as_ptr(), compare_op as c_int)
.assume_owned_or_err(any.py())
@ -1814,7 +1818,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
}
let py = self.py();
inner(self, other.to_object(py).attach_into(py), compare_op)
inner(self, other.to_object(py).into_bound(py), compare_op)
}
fn lt<O>(&self, other: O) -> PyResult<bool>
@ -1873,12 +1877,12 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
&self,
args: impl IntoPy<Py<PyTuple>>,
kwargs: Option<&PyDict>,
) -> PyResult<Py2<'py, PyAny>> {
) -> PyResult<Bound<'py, PyAny>> {
fn inner<'py>(
any: &Py2<'py, PyAny>,
args: Py2<'_, PyTuple>,
any: &Bound<'py, PyAny>,
args: Bound<'_, PyTuple>,
kwargs: Option<&PyDict>,
) -> PyResult<Py2<'py, PyAny>> {
) -> PyResult<Bound<'py, PyAny>> {
unsafe {
ffi::PyObject_Call(
any.as_ptr(),
@ -1890,10 +1894,10 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
}
let py = self.py();
inner(self, args.into_py(py).attach_into(py), kwargs)
inner(self, args.into_py(py).into_bound(py), kwargs)
}
fn call0(&self) -> PyResult<Py2<'py, PyAny>> {
fn call0(&self) -> PyResult<Bound<'py, PyAny>> {
cfg_if::cfg_if! {
if #[cfg(all(
not(PyPy),
@ -1909,7 +1913,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
}
}
fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<Py2<'py, PyAny>> {
fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<Bound<'py, PyAny>> {
self.call(args, None)
}
@ -1918,7 +1922,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
name: N,
args: A,
kwargs: Option<&PyDict>,
) -> PyResult<Py2<'py, PyAny>>
) -> PyResult<Bound<'py, PyAny>>
where
N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>,
@ -1927,7 +1931,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
.and_then(|method| method.call(args, kwargs))
}
fn call_method0<N>(&self, name: N) -> PyResult<Py2<'py, PyAny>>
fn call_method0<N>(&self, name: N) -> PyResult<Bound<'py, PyAny>>
where
N: IntoPy<Py<PyString>>,
{
@ -1937,7 +1941,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
// Optimized path on python 3.9+
unsafe {
let name = name.into_py(py).attach_into(py);
let name = name.into_py(py).into_bound(py);
ffi::PyObject_CallMethodNoArgs(self.as_ptr(), name.as_ptr()).assume_owned_or_err(py)
}
} else {
@ -1946,7 +1950,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
}
}
fn call_method1<N, A>(&self, name: N, args: A) -> PyResult<Py2<'py, PyAny>>
fn call_method1<N, A>(&self, name: N, args: A) -> PyResult<Bound<'py, PyAny>>
where
N: IntoPy<Py<PyString>>,
A: IntoPy<Py<PyTuple>>,
@ -1973,18 +1977,21 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
self.len().map(|l| l == 0)
}
fn get_item<K>(&self, key: K) -> PyResult<Py2<'py, PyAny>>
fn get_item<K>(&self, key: K) -> PyResult<Bound<'py, PyAny>>
where
K: ToPyObject,
{
fn inner<'py>(any: &Py2<'py, PyAny>, key: Py2<'_, PyAny>) -> PyResult<Py2<'py, PyAny>> {
fn inner<'py>(
any: &Bound<'py, PyAny>,
key: Bound<'_, PyAny>,
) -> PyResult<Bound<'py, PyAny>> {
unsafe {
ffi::PyObject_GetItem(any.as_ptr(), key.as_ptr()).assume_owned_or_err(any.py())
}
}
let py = self.py();
inner(self, key.to_object(py).attach_into(py))
inner(self, key.to_object(py).into_bound(py))
}
fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
@ -1992,7 +1999,11 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
K: ToPyObject,
V: ToPyObject,
{
fn inner(any: &Py2<'_, PyAny>, key: Py2<'_, PyAny>, value: Py2<'_, PyAny>) -> PyResult<()> {
fn inner(
any: &Bound<'_, PyAny>,
key: Bound<'_, PyAny>,
value: Bound<'_, PyAny>,
) -> PyResult<()> {
err::error_on_minusone(any.py(), unsafe {
ffi::PyObject_SetItem(any.as_ptr(), key.as_ptr(), value.as_ptr())
})
@ -2001,8 +2012,8 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
let py = self.py();
inner(
self,
key.to_object(py).attach_into(py),
value.to_object(py).attach_into(py),
key.to_object(py).into_bound(py),
value.to_object(py).into_bound(py),
)
}
@ -2010,17 +2021,17 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
where
K: ToPyObject,
{
fn inner(any: &Py2<'_, PyAny>, key: Py2<'_, PyAny>) -> PyResult<()> {
fn inner(any: &Bound<'_, PyAny>, key: Bound<'_, PyAny>) -> PyResult<()> {
err::error_on_minusone(any.py(), unsafe {
ffi::PyObject_DelItem(any.as_ptr(), key.as_ptr())
})
}
let py = self.py();
inner(self, key.to_object(py).attach_into(py))
inner(self, key.to_object(py).into_bound(py))
}
fn iter(&self) -> PyResult<Py2<'py, PyIterator>> {
fn iter(&self) -> PyResult<Bound<'py, PyIterator>> {
PyIterator::from_object2(self)
}
@ -2034,7 +2045,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
}
#[inline]
fn downcast<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError2<'_, 'py>>
fn downcast<T>(&self) -> Result<&Bound<'py, T>, DowncastError<'_, 'py>>
where
T: PyTypeCheck,
{
@ -2042,12 +2053,12 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
// Safety: type_check is responsible for ensuring that the type is correct
Ok(unsafe { self.downcast_unchecked() })
} else {
Err(PyDowncastError2::new(self, T::NAME))
Err(DowncastError::new(self, T::NAME))
}
}
#[inline]
fn downcast_into<T>(self) -> Result<Py2<'py, T>, PyDowncastIntoError<'py>>
fn downcast_into<T>(self) -> Result<Bound<'py, T>, DowncastIntoError<'py>>
where
T: PyTypeCheck,
{
@ -2055,12 +2066,12 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
// Safety: type_check is responsible for ensuring that the type is correct
Ok(unsafe { self.downcast_into_unchecked() })
} else {
Err(PyDowncastIntoError::new(self, T::NAME))
Err(DowncastIntoError::new(self, T::NAME))
}
}
#[inline]
fn downcast_exact<T>(&self) -> Result<&Py2<'py, T>, PyDowncastError2<'_, 'py>>
fn downcast_exact<T>(&self) -> Result<&Bound<'py, T>, DowncastError<'_, 'py>>
where
T: PyTypeInfo,
{
@ -2068,12 +2079,12 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
// Safety: is_exact_instance_of is responsible for ensuring that the type is correct
Ok(unsafe { self.downcast_unchecked() })
} else {
Err(PyDowncastError2::new(self, T::NAME))
Err(DowncastError::new(self, T::NAME))
}
}
#[inline]
fn downcast_into_exact<T>(self) -> Result<Py2<'py, T>, PyDowncastIntoError<'py>>
fn downcast_into_exact<T>(self) -> Result<Bound<'py, T>, DowncastIntoError<'py>>
where
T: PyTypeInfo,
{
@ -2081,17 +2092,17 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
// Safety: is_exact_instance_of is responsible for ensuring that the type is correct
Ok(unsafe { self.downcast_into_unchecked() })
} else {
Err(PyDowncastIntoError::new(self, T::NAME))
Err(DowncastIntoError::new(self, T::NAME))
}
}
#[inline]
unsafe fn downcast_unchecked<T>(&self) -> &Py2<'py, T> {
&*(self as *const Py2<'py, PyAny>).cast()
unsafe fn downcast_unchecked<T>(&self) -> &Bound<'py, T> {
&*(self as *const Bound<'py, PyAny>).cast()
}
#[inline]
unsafe fn downcast_into_unchecked<T>(self) -> Py2<'py, T> {
unsafe fn downcast_into_unchecked<T>(self) -> Bound<'py, T> {
std::mem::transmute(self)
}
@ -2106,7 +2117,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
unsafe { ffi::Py_REFCNT(self.as_ptr()) }
}
fn repr(&self) -> PyResult<Py2<'py, PyString>> {
fn repr(&self) -> PyResult<Bound<'py, PyString>> {
unsafe {
ffi::PyObject_Repr(self.as_ptr())
.assume_owned_or_err(self.py())
@ -2114,7 +2125,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
}
}
fn str(&self) -> PyResult<Py2<'py, PyString>> {
fn str(&self) -> PyResult<Bound<'py, PyString>> {
unsafe {
ffi::PyObject_Str(self.as_ptr())
.assume_owned_or_err(self.py())
@ -2134,7 +2145,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
Ok(v as usize)
}
fn dir(&self) -> Py2<'py, PyList> {
fn dir(&self) -> Bound<'py, PyList> {
unsafe {
ffi::PyObject_Dir(self.as_ptr())
.assume_owned(self.py())
@ -2143,14 +2154,14 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
}
#[inline]
fn is_instance(&self, ty: &Py2<'py, PyAny>) -> PyResult<bool> {
fn is_instance(&self, ty: &Bound<'py, PyAny>) -> PyResult<bool> {
let result = unsafe { ffi::PyObject_IsInstance(self.as_ptr(), ty.as_ptr()) };
err::error_on_minusone(self.py(), result)?;
Ok(result == 1)
}
#[inline]
fn is_exact_instance(&self, ty: &Py2<'py, PyAny>) -> bool {
fn is_exact_instance(&self, ty: &Bound<'py, PyAny>) -> bool {
self.get_type().is(ty)
}
@ -2168,7 +2179,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
where
V: ToPyObject,
{
fn inner(any: &Py2<'_, PyAny>, value: Py2<'_, PyAny>) -> PyResult<bool> {
fn inner(any: &Bound<'_, PyAny>, value: Bound<'_, PyAny>) -> PyResult<bool> {
match unsafe { ffi::PySequence_Contains(any.as_ptr(), value.as_ptr()) } {
0 => Ok(false),
1 => Ok(true),
@ -2177,12 +2188,12 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> {
}
let py = self.py();
inner(self, value.to_object(py).attach_into(py))
inner(self, value.to_object(py).into_bound(py))
}
#[cfg(not(PyPy))]
fn py_super(&self) -> PyResult<Py2<'py, PySuper>> {
PySuper::new2(Py2::borrowed_from_gil_ref(&self.get_type()), self)
fn py_super(&self) -> PyResult<Bound<'py, PySuper>> {
PySuper::new2(Bound::borrowed_from_gil_ref(&self.get_type()), self)
}
}

View file

@ -1,7 +1,7 @@
#[cfg(feature = "experimental-inspect")]
use crate::inspect::types::TypeInfo;
use crate::{
exceptions::PyTypeError, ffi, instance::Py2, FromPyObject, IntoPy, PyAny, PyObject, PyResult,
exceptions::PyTypeError, ffi, instance::Bound, FromPyObject, IntoPy, PyAny, PyObject, PyResult,
Python, ToPyObject,
};
@ -21,13 +21,13 @@ impl PyBool {
/// Gets whether this boolean is `true`.
#[inline]
pub fn is_true(&self) -> bool {
Py2::borrowed_from_gil_ref(&self).is_true()
Bound::borrowed_from_gil_ref(&self).is_true()
}
}
/// Implementation of functionality for [`PyBool`].
///
/// These methods are defined for the `Py2<'py, PyBool>` smart pointer, so to use method call
/// These methods are defined for the `Bound<'py, PyBool>` smart pointer, so to use method call
/// syntax these methods are separated into a trait, because stable Rust does not yet support
/// `arbitrary_self_types`.
#[doc(alias = "PyBool")]
@ -36,7 +36,7 @@ pub trait PyBoolMethods<'py> {
fn is_true(&self) -> bool;
}
impl<'py> PyBoolMethods<'py> for Py2<'py, PyBool> {
impl<'py> PyBoolMethods<'py> for Bound<'py, PyBool> {
#[inline]
fn is_true(&self) -> bool {
self.as_ptr() == unsafe { crate::ffi::Py_True() }

View file

@ -1,5 +1,5 @@
use crate::err::{PyErr, PyResult};
use crate::instance::{Py2, Py2Borrowed};
use crate::instance::{Borrowed, Bound};
use crate::{ffi, AsPyPointer, Py, PyAny, 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 {
Py2::borrowed_from_gil_ref(&self).len()
Bound::borrowed_from_gil_ref(&self).len()
}
/// Checks if the bytearray is empty.
pub fn is_empty(&self) -> bool {
Py2::borrowed_from_gil_ref(&self).is_empty()
Bound::borrowed_from_gil_ref(&self).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 {
Py2::borrowed_from_gil_ref(&self).data()
Bound::borrowed_from_gil_ref(&self).data()
}
/// Extracts a slice of the `ByteArray`'s entire buffer.
@ -188,7 +188,7 @@ impl PyByteArray {
/// }
/// ```
pub unsafe fn as_bytes(&self) -> &[u8] {
Py2Borrowed::from_gil_ref(self).as_bytes()
Borrowed::from_gil_ref(self).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] {
Py2Borrowed::from_gil_ref(self).as_bytes_mut()
Borrowed::from_gil_ref(self).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> {
Py2::borrowed_from_gil_ref(&self).to_vec()
Bound::borrowed_from_gil_ref(&self).to_vec()
}
/// Resizes the bytearray object to the new length `len`.
@ -230,13 +230,13 @@ 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<()> {
Py2::borrowed_from_gil_ref(&self).resize(len)
Bound::borrowed_from_gil_ref(&self).resize(len)
}
}
/// Implementation of functionality for [`PyByteArray`].
///
/// These methods are defined for the `Py2<'py, PyByteArray>` smart pointer, so to use method call
/// These methods are defined for the `Bound<'py, PyByteArray>` smart pointer, so to use method call
/// syntax these methods are separated into a trait, because stable Rust does not yet support
/// `arbitrary_self_types`.
#[doc(alias = "PyByteArray")]
@ -388,7 +388,7 @@ pub trait PyByteArrayMethods<'py> {
fn resize(&self, len: usize) -> PyResult<()>;
}
impl<'py> PyByteArrayMethods<'py> for Py2<'py, PyByteArray> {
impl<'py> PyByteArrayMethods<'py> for Bound<'py, PyByteArray> {
#[inline]
fn len(&self) -> usize {
// non-negative Py_ssize_t should always fit into Rust usize
@ -400,16 +400,16 @@ impl<'py> PyByteArrayMethods<'py> for Py2<'py, PyByteArray> {
}
fn data(&self) -> *mut u8 {
Py2Borrowed::from(self).data()
Borrowed::from(self).data()
}
unsafe fn as_bytes(&self) -> &[u8] {
Py2Borrowed::from(self).as_bytes()
Borrowed::from(self).as_bytes()
}
#[allow(clippy::mut_from_ref)]
unsafe fn as_bytes_mut(&self) -> &mut [u8] {
Py2Borrowed::from(self).as_bytes_mut()
Borrowed::from(self).as_bytes_mut()
}
fn to_vec(&self) -> Vec<u8> {
@ -428,7 +428,7 @@ impl<'py> PyByteArrayMethods<'py> for Py2<'py, PyByteArray> {
}
}
impl<'a> Py2Borrowed<'a, '_, PyByteArray> {
impl<'a> Borrowed<'a, '_, PyByteArray> {
fn data(&self) -> *mut u8 {
unsafe { ffi::PyByteArray_AsString(self.as_ptr()).cast() }
}

View file

@ -1,4 +1,4 @@
use crate::instance::{Py2, Py2Borrowed};
use crate::instance::{Borrowed, Bound};
use crate::{ffi, FromPyObject, IntoPy, Py, PyAny, PyResult, Python, ToPyObject};
use std::borrow::Cow;
use std::ops::Index;
@ -89,29 +89,29 @@ impl PyBytes {
/// Gets the Python string as a byte slice.
#[inline]
pub fn as_bytes(&self) -> &[u8] {
Py2Borrowed::from_gil_ref(self).as_bytes()
Borrowed::from_gil_ref(self).as_bytes()
}
}
/// Implementation of functionality for [`PyBytes`].
///
/// These methods are defined for the `Py2<'py, PyBytes>` smart pointer, so to use method call
/// These methods are defined for the `Bound<'py, PyBytes>` smart pointer, so to use method call
/// syntax these methods are separated into a trait, because stable Rust does not yet support
/// `arbitrary_self_types`.
#[doc(alias = "PyBytes")]
pub(crate) trait PyBytesMethods<'py> {
pub trait PyBytesMethods<'py> {
/// Gets the Python string as a byte slice.
fn as_bytes(&self) -> &[u8];
}
impl<'py> PyBytesMethods<'py> for Py2<'py, PyBytes> {
impl<'py> PyBytesMethods<'py> for Bound<'py, PyBytes> {
#[inline]
fn as_bytes(&self) -> &[u8] {
Py2Borrowed::from(self).as_bytes()
Borrowed::from(self).as_bytes()
}
}
impl<'a> Py2Borrowed<'a, '_, PyBytes> {
impl<'a> Borrowed<'a, '_, PyBytes> {
/// Gets the Python string as a byte slice.
#[allow(clippy::wrong_self_convention)]
fn as_bytes(self) -> &'a [u8] {
@ -129,7 +129,7 @@ impl Py<PyBytes> {
/// immutable, the result may be used for as long as the reference to
/// `self` is held, including when the GIL is released.
pub fn as_bytes<'a>(&'a self, py: Python<'_>) -> &'a [u8] {
self.attach_borrow(py).as_bytes()
self.bind_borrowed(py).as_bytes()
}
}

View file

@ -2,7 +2,7 @@ use super::PyMapping;
use crate::err::{self, PyErr, PyResult};
use crate::ffi::Py_ssize_t;
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::{Py2, Py2Borrowed};
use crate::instance::{Borrowed, Bound};
use crate::py_result_ext::PyResultExt;
use crate::types::any::PyAnyMethods;
use crate::types::{PyAny, PyList};
@ -82,26 +82,26 @@ impl PyDict {
///
/// This is equivalent to the Python expression `self.copy()`.
pub fn copy(&self) -> PyResult<&PyDict> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.copy()
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Empties an existing dictionary of all key-value pairs.
pub fn clear(&self) {
Py2::borrowed_from_gil_ref(&self).clear()
Bound::borrowed_from_gil_ref(&self).clear()
}
/// Return the number of items in the dictionary.
///
/// This is equivalent to the Python expression `len(self)`.
pub fn len(&self) -> usize {
Py2::borrowed_from_gil_ref(&self).len()
Bound::borrowed_from_gil_ref(&self).len()
}
/// Checks if the dict is empty, i.e. `len(self) == 0`.
pub fn is_empty(&self) -> bool {
Py2::borrowed_from_gil_ref(&self).is_empty()
Bound::borrowed_from_gil_ref(&self).is_empty()
}
/// Determines if the dictionary contains the specified key.
@ -111,7 +111,7 @@ impl PyDict {
where
K: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).contains(key)
Bound::borrowed_from_gil_ref(&self).contains(key)
}
/// Gets an item from the dictionary.
@ -160,7 +160,7 @@ impl PyDict {
where
K: ToPyObject,
{
match Py2::borrowed_from_gil_ref(&self).get_item(key) {
match Bound::borrowed_from_gil_ref(&self).get_item(key) {
Ok(Some(item)) => Ok(Some(item.into_gil_ref())),
Ok(None) => Ok(None),
Err(e) => Err(e),
@ -188,7 +188,7 @@ impl PyDict {
K: ToPyObject,
V: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).set_item(key, value)
Bound::borrowed_from_gil_ref(&self).set_item(key, value)
}
/// Deletes an item.
@ -198,28 +198,28 @@ impl PyDict {
where
K: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).del_item(key)
Bound::borrowed_from_gil_ref(&self).del_item(key)
}
/// Returns a list of dict keys.
///
/// This is equivalent to the Python expression `list(dict.keys())`.
pub fn keys(&self) -> &PyList {
Py2::borrowed_from_gil_ref(&self).keys().into_gil_ref()
Bound::borrowed_from_gil_ref(&self).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 {
Py2::borrowed_from_gil_ref(&self).values().into_gil_ref()
Bound::borrowed_from_gil_ref(&self).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 {
Py2::borrowed_from_gil_ref(&self).items().into_gil_ref()
Bound::borrowed_from_gil_ref(&self).items().into_gil_ref()
}
/// Returns an iterator of `(key, value)` pairs in this dictionary.
@ -230,7 +230,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(Py2::borrowed_from_gil_ref(&self).iter())
PyDictIterator(Bound::borrowed_from_gil_ref(&self).iter())
}
/// Returns `self` cast as a `PyMapping`.
@ -243,7 +243,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<()> {
Py2::borrowed_from_gil_ref(&self).update(Py2::borrowed_from_gil_ref(&other))
Bound::borrowed_from_gil_ref(&self).update(Bound::borrowed_from_gil_ref(&other))
}
/// Add key/value pairs from another dictionary to this one only when they do not exist in this.
@ -255,21 +255,21 @@ 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<()> {
Py2::borrowed_from_gil_ref(&self).update_if_missing(Py2::borrowed_from_gil_ref(&other))
Bound::borrowed_from_gil_ref(&self).update_if_missing(Bound::borrowed_from_gil_ref(&other))
}
}
/// Implementation of functionality for [`PyDict`].
///
/// These methods are defined for the `Py2<'py, PyDict>` smart pointer, so to use method call
/// These methods are defined for the `Bound<'py, PyDict>` smart pointer, so to use method call
/// syntax these methods are separated into a trait, because stable Rust does not yet support
/// `arbitrary_self_types`.
#[doc(alias = "PyDict")]
pub(crate) trait PyDictMethods<'py> {
pub trait PyDictMethods<'py> {
/// Returns a new dictionary that contains the same key-value pairs as self.
///
/// This is equivalent to the Python expression `self.copy()`.
fn copy(&self) -> PyResult<Py2<'py, PyDict>>;
fn copy(&self) -> PyResult<Bound<'py, PyDict>>;
/// Empties an existing dictionary of all key-value pairs.
fn clear(&self);
@ -294,7 +294,7 @@ pub(crate) trait PyDictMethods<'py> {
/// Returns `None` if the item is not present, or if an error occurs.
///
/// To get a `KeyError` for non-existing keys, use `PyAny::get_item`.
fn get_item<K>(&self, key: K) -> PyResult<Option<Py2<'py, PyAny>>>
fn get_item<K>(&self, key: K) -> PyResult<Option<Bound<'py, PyAny>>>
where
K: ToPyObject;
@ -316,17 +316,17 @@ pub(crate) trait PyDictMethods<'py> {
/// Returns a list of dict keys.
///
/// This is equivalent to the Python expression `list(dict.keys())`.
fn keys(&self) -> Py2<'py, PyList>;
fn keys(&self) -> Bound<'py, PyList>;
/// Returns a list of dict values.
///
/// This is equivalent to the Python expression `list(dict.values())`.
fn values(&self) -> Py2<'py, PyList>;
fn values(&self) -> Bound<'py, PyList>;
/// Returns a list of dict items.
///
/// This is equivalent to the Python expression `list(dict.items())`.
fn items(&self) -> Py2<'py, PyList>;
fn items(&self) -> Bound<'py, PyList>;
/// Returns an iterator of `(key, value)` pairs in this dictionary.
///
@ -335,16 +335,16 @@ pub(crate) trait PyDictMethods<'py> {
/// If PyO3 detects that the dictionary is mutated during iteration, it will panic.
/// It is allowed to modify values as you iterate over the dictionary, but only
/// so long as the set of keys does not change.
fn iter(&self) -> PyDictIterator2<'py>;
fn iter(&self) -> BoundDictIterator<'py>;
/// Returns `self` cast as a `PyMapping`.
fn as_mapping(&self) -> &Py2<'py, PyMapping>;
fn as_mapping(&self) -> &Bound<'py, PyMapping>;
/// Update this dictionary with the key/value pairs from another.
///
/// 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.
fn update(&self, other: &Py2<'_, PyMapping>) -> PyResult<()>;
fn update(&self, other: &Bound<'_, PyMapping>) -> PyResult<()>;
/// Add key/value pairs from another dictionary to this one only when they do not exist in this.
///
@ -354,11 +354,11 @@ pub(crate) trait PyDictMethods<'py> {
///
/// 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`.
fn update_if_missing(&self, other: &Py2<'_, PyMapping>) -> PyResult<()>;
fn update_if_missing(&self, other: &Bound<'_, PyMapping>) -> PyResult<()>;
}
impl<'py> PyDictMethods<'py> for Py2<'py, PyDict> {
fn copy(&self) -> PyResult<Py2<'py, PyDict>> {
impl<'py> PyDictMethods<'py> for Bound<'py, PyDict> {
fn copy(&self) -> PyResult<Bound<'py, PyDict>> {
unsafe {
ffi::PyDict_Copy(self.as_ptr())
.assume_owned_or_err(self.py())
@ -382,7 +382,7 @@ impl<'py> PyDictMethods<'py> for Py2<'py, PyDict> {
where
K: ToPyObject,
{
fn inner(dict: &Py2<'_, PyDict>, key: Py2<'_, PyAny>) -> PyResult<bool> {
fn inner(dict: &Bound<'_, PyDict>, key: Bound<'_, PyAny>) -> PyResult<bool> {
match unsafe { ffi::PyDict_Contains(dict.as_ptr(), key.as_ptr()) } {
1 => Ok(true),
0 => Ok(false),
@ -391,22 +391,22 @@ impl<'py> PyDictMethods<'py> for Py2<'py, PyDict> {
}
let py = self.py();
inner(self, key.to_object(py).attach_into(py))
inner(self, key.to_object(py).into_bound(py))
}
fn get_item<K>(&self, key: K) -> PyResult<Option<Py2<'py, PyAny>>>
fn get_item<K>(&self, key: K) -> PyResult<Option<Bound<'py, PyAny>>>
where
K: ToPyObject,
{
fn inner<'py>(
dict: &Py2<'py, PyDict>,
key: Py2<'_, PyAny>,
) -> PyResult<Option<Py2<'py, PyAny>>> {
dict: &Bound<'py, PyDict>,
key: Bound<'_, PyAny>,
) -> PyResult<Option<Bound<'py, PyAny>>> {
let py = dict.py();
match unsafe {
ffi::PyDict_GetItemWithError(dict.as_ptr(), key.as_ptr())
.assume_borrowed_or_opt(py)
.map(Py2Borrowed::to_owned)
.map(Borrowed::to_owned)
} {
some @ Some(_) => Ok(some),
None => PyErr::take(py).map(Err).transpose(),
@ -414,7 +414,7 @@ impl<'py> PyDictMethods<'py> for Py2<'py, PyDict> {
}
let py = self.py();
inner(self, key.to_object(py).attach_into(py))
inner(self, key.to_object(py).into_bound(py))
}
fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
@ -423,9 +423,9 @@ impl<'py> PyDictMethods<'py> for Py2<'py, PyDict> {
V: ToPyObject,
{
fn inner(
dict: &Py2<'_, PyDict>,
key: Py2<'_, PyAny>,
value: Py2<'_, PyAny>,
dict: &Bound<'_, PyDict>,
key: Bound<'_, PyAny>,
value: Bound<'_, PyAny>,
) -> PyResult<()> {
err::error_on_minusone(dict.py(), unsafe {
ffi::PyDict_SetItem(dict.as_ptr(), key.as_ptr(), value.as_ptr())
@ -435,8 +435,8 @@ impl<'py> PyDictMethods<'py> for Py2<'py, PyDict> {
let py = self.py();
inner(
self,
key.to_object(py).attach_into(py),
value.to_object(py).attach_into(py),
key.to_object(py).into_bound(py),
value.to_object(py).into_bound(py),
)
}
@ -444,17 +444,17 @@ impl<'py> PyDictMethods<'py> for Py2<'py, PyDict> {
where
K: ToPyObject,
{
fn inner(dict: &Py2<'_, PyDict>, key: Py2<'_, PyAny>) -> PyResult<()> {
fn inner(dict: &Bound<'_, PyDict>, key: Bound<'_, PyAny>) -> PyResult<()> {
err::error_on_minusone(dict.py(), unsafe {
ffi::PyDict_DelItem(dict.as_ptr(), key.as_ptr())
})
}
let py = self.py();
inner(self, key.to_object(py).attach_into(py))
inner(self, key.to_object(py).into_bound(py))
}
fn keys(&self) -> Py2<'py, PyList> {
fn keys(&self) -> Bound<'py, PyList> {
unsafe {
ffi::PyDict_Keys(self.as_ptr())
.assume_owned(self.py())
@ -462,7 +462,7 @@ impl<'py> PyDictMethods<'py> for Py2<'py, PyDict> {
}
}
fn values(&self) -> Py2<'py, PyList> {
fn values(&self) -> Bound<'py, PyList> {
unsafe {
ffi::PyDict_Values(self.as_ptr())
.assume_owned(self.py())
@ -470,7 +470,7 @@ impl<'py> PyDictMethods<'py> for Py2<'py, PyDict> {
}
}
fn items(&self) -> Py2<'py, PyList> {
fn items(&self) -> Bound<'py, PyList> {
unsafe {
ffi::PyDict_Items(self.as_ptr())
.assume_owned(self.py())
@ -478,28 +478,28 @@ impl<'py> PyDictMethods<'py> for Py2<'py, PyDict> {
}
}
fn iter(&self) -> PyDictIterator2<'py> {
PyDictIterator2::new(self.clone())
fn iter(&self) -> BoundDictIterator<'py> {
BoundDictIterator::new(self.clone())
}
fn as_mapping(&self) -> &Py2<'py, PyMapping> {
fn as_mapping(&self) -> &Bound<'py, PyMapping> {
unsafe { self.downcast_unchecked() }
}
fn update(&self, other: &Py2<'_, PyMapping>) -> PyResult<()> {
fn update(&self, other: &Bound<'_, PyMapping>) -> PyResult<()> {
err::error_on_minusone(self.py(), unsafe {
ffi::PyDict_Update(self.as_ptr(), other.as_ptr())
})
}
fn update_if_missing(&self, other: &Py2<'_, PyMapping>) -> PyResult<()> {
fn update_if_missing(&self, other: &Bound<'_, PyMapping>) -> PyResult<()> {
err::error_on_minusone(self.py(), unsafe {
ffi::PyDict_Merge(self.as_ptr(), other.as_ptr(), 0)
})
}
}
fn dict_len(dict: &Py2<'_, PyDict>) -> Py_ssize_t {
fn dict_len(dict: &Bound<'_, PyDict>) -> Py_ssize_t {
#[cfg(any(not(Py_3_8), PyPy, Py_LIMITED_API))]
unsafe {
ffi::PyDict_Size(dict.as_ptr())
@ -512,7 +512,7 @@ fn dict_len(dict: &Py2<'_, PyDict>) -> Py_ssize_t {
}
/// PyO3 implementation of an iterator for a Python `dict` object.
pub struct PyDictIterator<'py>(PyDictIterator2<'py>);
pub struct PyDictIterator<'py>(BoundDictIterator<'py>);
impl<'py> Iterator for PyDictIterator<'py> {
type Item = (&'py PyAny, &'py PyAny);
@ -545,15 +545,15 @@ impl<'a> IntoIterator for &'a PyDict {
}
/// PyO3 implementation of an iterator for a Python `dict` object.
pub(crate) struct PyDictIterator2<'py> {
dict: Py2<'py, PyDict>,
pub struct BoundDictIterator<'py> {
dict: Bound<'py, PyDict>,
ppos: ffi::Py_ssize_t,
di_used: ffi::Py_ssize_t,
len: ffi::Py_ssize_t,
}
impl<'py> Iterator for PyDictIterator2<'py> {
type Item = (Py2<'py, PyAny>, Py2<'py, PyAny>);
impl<'py> Iterator for BoundDictIterator<'py> {
type Item = (Bound<'py, PyAny>, Bound<'py, PyAny>);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
@ -610,16 +610,16 @@ impl<'py> Iterator for PyDictIterator2<'py> {
}
}
impl<'py> ExactSizeIterator for PyDictIterator2<'py> {
impl<'py> ExactSizeIterator for BoundDictIterator<'py> {
fn len(&self) -> usize {
self.len as usize
}
}
impl<'py> PyDictIterator2<'py> {
fn new(dict: Py2<'py, PyDict>) -> Self {
impl<'py> BoundDictIterator<'py> {
fn new(dict: Bound<'py, PyDict>) -> Self {
let len = dict_len(&dict);
PyDictIterator2 {
BoundDictIterator {
dict,
ppos: 0,
di_used: len,
@ -628,21 +628,21 @@ impl<'py> PyDictIterator2<'py> {
}
}
impl<'py> IntoIterator for &'_ Py2<'py, PyDict> {
type Item = (Py2<'py, PyAny>, Py2<'py, PyAny>);
type IntoIter = PyDictIterator2<'py>;
impl<'py> IntoIterator for &'_ Bound<'py, PyDict> {
type Item = (Bound<'py, PyAny>, Bound<'py, PyAny>);
type IntoIter = BoundDictIterator<'py>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'py> IntoIterator for Py2<'py, PyDict> {
type Item = (Py2<'py, PyAny>, Py2<'py, PyAny>);
type IntoIter = PyDictIterator2<'py>;
impl<'py> IntoIterator for Bound<'py, PyDict> {
type Item = (Bound<'py, PyAny>, Bound<'py, PyAny>);
type IntoIter = BoundDictIterator<'py>;
fn into_iter(self) -> Self::IntoIter {
PyDictIterator2::new(self)
BoundDictIterator::new(self)
}
}

View file

@ -1,7 +1,7 @@
#[cfg(feature = "experimental-inspect")]
use crate::inspect::types::TypeInfo;
use crate::{
ffi, instance::Py2, FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject, PyResult,
ffi, instance::Bound, FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject, PyResult,
Python, ToPyObject,
};
use std::os::raw::c_double;
@ -29,13 +29,13 @@ impl PyFloat {
/// Gets the value of this float.
pub fn value(&self) -> c_double {
Py2::borrowed_from_gil_ref(&self).value()
Bound::borrowed_from_gil_ref(&self).value()
}
}
/// Implementation of functionality for [`PyFloat`].
///
/// These methods are defined for the `Py2<'py, PyFloat>` smart pointer, so to use method call
/// These methods are defined for the `Bound<'py, PyFloat>` smart pointer, so to use method call
/// syntax these methods are separated into a trait, because stable Rust does not yet support
/// `arbitrary_self_types`.
#[doc(alias = "PyFloat")]
@ -44,7 +44,7 @@ pub trait PyFloatMethods<'py> {
fn value(&self) -> c_double;
}
impl<'py> PyFloatMethods<'py> for Py2<'py, PyFloat> {
impl<'py> PyFloatMethods<'py> for Bound<'py, PyFloat> {
fn value(&self) -> c_double {
#[cfg(not(Py_LIMITED_API))]
unsafe {

View file

@ -1,7 +1,7 @@
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::py_result_ext::PyResultExt;
use crate::{
ffi, AsPyPointer, Py2, PyAny, PyDowncastError, PyErr, PyNativeType, PyResult, PyTypeCheck,
ffi, AsPyPointer, Bound, PyAny, PyDowncastError, PyErr, PyNativeType, PyResult, PyTypeCheck,
};
/// A Python iterator object.
@ -34,10 +34,10 @@ impl PyIterator {
///
/// Equivalent to Python's built-in `iter` function.
pub fn from_object(obj: &PyAny) -> PyResult<&PyIterator> {
Self::from_object2(Py2::borrowed_from_gil_ref(&obj)).map(Py2::into_gil_ref)
Self::from_object2(Bound::borrowed_from_gil_ref(&obj)).map(Bound::into_gil_ref)
}
pub(crate) fn from_object2<'py>(obj: &Py2<'py, PyAny>) -> PyResult<Py2<'py, PyIterator>> {
pub(crate) fn from_object2<'py>(obj: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyIterator>> {
unsafe {
ffi::PyObject_GetIter(obj.as_ptr())
.assume_owned_or_err(obj.py())

View file

@ -4,10 +4,10 @@ use std::iter::FusedIterator;
use crate::err::{self, PyResult};
use crate::ffi::{self, Py_ssize_t};
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::Py2Borrowed;
use crate::instance::Borrowed;
use crate::internal_tricks::get_ssize_index;
use crate::types::{PySequence, PyTuple};
use crate::{Py2, PyAny, PyObject, Python, ToPyObject};
use crate::{Bound, PyAny, PyObject, Python, ToPyObject};
use crate::types::any::PyAnyMethods;
use crate::types::sequence::PySequenceMethods;
@ -23,7 +23,7 @@ pyobject_native_type_core!(PyList, pyobject_native_static_type_object!(ffi::PyLi
pub(crate) fn new_from_iter<'py>(
py: Python<'py>,
elements: &mut dyn ExactSizeIterator<Item = PyObject>,
) -> Py2<'py, PyList> {
) -> Bound<'py, PyList> {
unsafe {
// PyList_New checks for overflow but has a bad error message, so we check ourselves
let len: Py_ssize_t = elements
@ -33,7 +33,7 @@ pub(crate) fn new_from_iter<'py>(
let ptr = ffi::PyList_New(len);
// We create the `Py2` pointer here for two reasons:
// We create the `Bound` pointer here for two reasons:
// - panics if the ptr is null
// - its Drop cleans up the list if user code or the asserts panic.
let list = ptr.assume_owned(py).downcast_into_unchecked();
@ -98,12 +98,12 @@ impl PyList {
/// Returns the length of the list.
pub fn len(&self) -> usize {
Py2::borrowed_from_gil_ref(&self).len()
Bound::borrowed_from_gil_ref(&self).len()
}
/// Checks if the list is empty.
pub fn is_empty(&self) -> bool {
Py2::borrowed_from_gil_ref(&self).is_empty()
Bound::borrowed_from_gil_ref(&self).is_empty()
}
/// Returns `self` cast as a `PySequence`.
@ -122,9 +122,9 @@ impl PyList {
/// });
/// ```
pub fn get_item(&self, index: usize) -> PyResult<&PyAny> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.get_item(index)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Gets the list item at the specified index. Undefined behavior on bad index. Use with caution.
@ -134,7 +134,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 {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.get_item_unchecked(index)
.into_gil_ref()
}
@ -144,7 +144,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 {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.get_slice(low, high)
.into_gil_ref()
}
@ -156,7 +156,7 @@ impl PyList {
where
I: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).set_item(index, item)
Bound::borrowed_from_gil_ref(&self).set_item(index, item)
}
/// Deletes the `index`th element of self.
@ -164,7 +164,7 @@ impl PyList {
/// This is equivalent to the Python statement `del self[i]`.
#[inline]
pub fn del_item(&self, index: usize) -> PyResult<()> {
Py2::borrowed_from_gil_ref(&self).del_item(index)
Bound::borrowed_from_gil_ref(&self).del_item(index)
}
/// Assigns the sequence `seq` to the slice of `self` from `low` to `high`.
@ -172,7 +172,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<()> {
Py2::borrowed_from_gil_ref(&self).set_slice(low, high, Py2::borrowed_from_gil_ref(&seq))
Bound::borrowed_from_gil_ref(&self).set_slice(low, high, Bound::borrowed_from_gil_ref(&seq))
}
/// Deletes the slice from `low` to `high` from `self`.
@ -180,7 +180,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<()> {
Py2::borrowed_from_gil_ref(&self).del_slice(low, high)
Bound::borrowed_from_gil_ref(&self).del_slice(low, high)
}
/// Appends an item to the list.
@ -188,7 +188,7 @@ impl PyList {
where
I: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).append(item)
Bound::borrowed_from_gil_ref(&self).append(item)
}
/// Inserts an item at the specified index.
@ -198,7 +198,7 @@ impl PyList {
where
I: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).insert(index, item)
Bound::borrowed_from_gil_ref(&self).insert(index, item)
}
/// Determines if self contains `value`.
@ -209,7 +209,7 @@ impl PyList {
where
V: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).contains(value)
Bound::borrowed_from_gil_ref(&self).contains(value)
}
/// Returns the first index `i` for which `self[i] == value`.
@ -220,29 +220,31 @@ impl PyList {
where
V: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).index(value)
Bound::borrowed_from_gil_ref(&self).index(value)
}
/// Returns an iterator over this list's items.
pub fn iter(&self) -> PyListIterator<'_> {
PyListIterator(Py2::borrowed_from_gil_ref(&self).iter())
PyListIterator(Bound::borrowed_from_gil_ref(&self).iter())
}
/// Sorts the list in-place. Equivalent to the Python expression `l.sort()`.
pub fn sort(&self) -> PyResult<()> {
Py2::borrowed_from_gil_ref(&self).sort()
Bound::borrowed_from_gil_ref(&self).sort()
}
/// Reverses the list in-place. Equivalent to the Python expression `l.reverse()`.
pub fn reverse(&self) -> PyResult<()> {
Py2::borrowed_from_gil_ref(&self).reverse()
Bound::borrowed_from_gil_ref(&self).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 {
Py2::borrowed_from_gil_ref(&self).to_tuple().into_gil_ref()
Bound::borrowed_from_gil_ref(&self)
.to_tuple()
.into_gil_ref()
}
}
@ -250,11 +252,11 @@ index_impls!(PyList, "list", PyList::len, PyList::get_slice);
/// Implementation of functionality for [`PyList`].
///
/// These methods are defined for the `Py2<'py, PyList>` smart pointer, so to use method call
/// These methods are defined for the `Bound<'py, PyList>` smart pointer, so to use method call
/// syntax these methods are separated into a trait, because stable Rust does not yet support
/// `arbitrary_self_types`.
#[doc(alias = "PyList")]
pub(crate) trait PyListMethods<'py> {
pub trait PyListMethods<'py> {
/// Returns the length of the list.
fn len(&self) -> usize;
@ -262,7 +264,7 @@ pub(crate) trait PyListMethods<'py> {
fn is_empty(&self) -> bool;
/// Returns `self` cast as a `PySequence`.
fn as_sequence(&self) -> &Py2<'py, PySequence>;
fn as_sequence(&self) -> &Bound<'py, PySequence>;
/// Gets the list item at the specified index.
/// # Example
@ -274,7 +276,7 @@ pub(crate) trait PyListMethods<'py> {
/// assert_eq!(obj.unwrap().extract::<i32>().unwrap(), 2);
/// });
/// ```
fn get_item(&self, index: usize) -> PyResult<Py2<'py, PyAny>>;
fn get_item(&self, index: usize) -> PyResult<Bound<'py, PyAny>>;
/// Gets the list item at the specified index. Undefined behavior on bad index. Use with caution.
///
@ -282,13 +284,13 @@ pub(crate) trait PyListMethods<'py> {
///
/// Caller must verify that the index is within the bounds of the list.
#[cfg(not(Py_LIMITED_API))]
unsafe fn get_item_unchecked(&self, index: usize) -> Py2<'py, PyAny>;
unsafe fn get_item_unchecked(&self, index: usize) -> Bound<'py, PyAny>;
/// Takes the slice `self[low:high]` and returns it as a new list.
///
/// Indices must be nonnegative, and out-of-range indices are clipped to
/// `self.len()`.
fn get_slice(&self, low: usize, high: usize) -> Py2<'py, PyList>;
fn get_slice(&self, low: usize, high: usize) -> Bound<'py, PyList>;
/// Sets the item at the specified index.
///
@ -305,7 +307,7 @@ pub(crate) trait PyListMethods<'py> {
/// Assigns the sequence `seq` to the slice of `self` from `low` to `high`.
///
/// This is equivalent to the Python statement `self[low:high] = v`.
fn set_slice(&self, low: usize, high: usize, seq: &Py2<'_, PyAny>) -> PyResult<()>;
fn set_slice(&self, low: usize, high: usize, seq: &Bound<'_, PyAny>) -> PyResult<()>;
/// Deletes the slice from `low` to `high` from `self`.
///
@ -339,7 +341,7 @@ pub(crate) trait PyListMethods<'py> {
V: ToPyObject;
/// Returns an iterator over this list's items.
fn iter(&self) -> PyListIterator2<'py>;
fn iter(&self) -> BoundListIterator<'py>;
/// Sorts the list in-place. Equivalent to the Python expression `l.sort()`.
fn sort(&self) -> PyResult<()>;
@ -350,10 +352,10 @@ pub(crate) trait PyListMethods<'py> {
/// 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)`.
fn to_tuple(&self) -> Py2<'py, PyTuple>;
fn to_tuple(&self) -> Bound<'py, PyTuple>;
}
impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
impl<'py> PyListMethods<'py> for Bound<'py, PyList> {
/// Returns the length of the list.
fn len(&self) -> usize {
unsafe {
@ -373,7 +375,7 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
}
/// Returns `self` cast as a `PySequence`.
fn as_sequence(&self) -> &Py2<'py, PySequence> {
fn as_sequence(&self) -> &Bound<'py, PySequence> {
unsafe { self.downcast_unchecked() }
}
@ -387,12 +389,12 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
/// assert_eq!(obj.unwrap().extract::<i32>().unwrap(), 2);
/// });
/// ```
fn get_item(&self, index: usize) -> PyResult<Py2<'py, PyAny>> {
fn get_item(&self, index: usize) -> PyResult<Bound<'py, PyAny>> {
unsafe {
// PyList_GetItem return borrowed ptr; must make owned for safety (see #890).
ffi::PyList_GetItem(self.as_ptr(), index as Py_ssize_t)
.assume_borrowed_or_err(self.py())
.map(Py2Borrowed::to_owned)
.map(Borrowed::to_owned)
}
}
@ -402,7 +404,7 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
///
/// Caller must verify that the index is within the bounds of the list.
#[cfg(not(Py_LIMITED_API))]
unsafe fn get_item_unchecked(&self, index: usize) -> Py2<'py, PyAny> {
unsafe fn get_item_unchecked(&self, index: usize) -> Bound<'py, PyAny> {
// PyList_GET_ITEM return borrowed ptr; must make owned for safety (see #890).
ffi::PyList_GET_ITEM(self.as_ptr(), index as Py_ssize_t)
.assume_borrowed(self.py())
@ -413,7 +415,7 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
///
/// Indices must be nonnegative, and out-of-range indices are clipped to
/// `self.len()`.
fn get_slice(&self, low: usize, high: usize) -> Py2<'py, PyList> {
fn get_slice(&self, low: usize, high: usize) -> Bound<'py, PyList> {
unsafe {
ffi::PyList_GetSlice(self.as_ptr(), get_ssize_index(low), get_ssize_index(high))
.assume_owned(self.py())
@ -428,14 +430,14 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
where
I: ToPyObject,
{
fn inner(list: &Py2<'_, PyList>, index: usize, item: Py2<'_, PyAny>) -> PyResult<()> {
fn inner(list: &Bound<'_, PyList>, index: usize, item: Bound<'_, PyAny>) -> PyResult<()> {
err::error_on_minusone(list.py(), unsafe {
ffi::PyList_SetItem(list.as_ptr(), get_ssize_index(index), item.into_ptr())
})
}
let py = self.py();
inner(self, index, item.to_object(py).attach_into(py))
inner(self, index, item.to_object(py).into_bound(py))
}
/// Deletes the `index`th element of self.
@ -450,7 +452,7 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
///
/// This is equivalent to the Python statement `self[low:high] = v`.
#[inline]
fn set_slice(&self, low: usize, high: usize, seq: &Py2<'_, PyAny>) -> PyResult<()> {
fn set_slice(&self, low: usize, high: usize, seq: &Bound<'_, PyAny>) -> PyResult<()> {
err::error_on_minusone(self.py(), unsafe {
ffi::PyList_SetSlice(
self.as_ptr(),
@ -474,14 +476,14 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
where
I: ToPyObject,
{
fn inner(list: &Py2<'_, PyList>, item: Py2<'_, PyAny>) -> PyResult<()> {
fn inner(list: &Bound<'_, PyList>, item: Bound<'_, PyAny>) -> PyResult<()> {
err::error_on_minusone(list.py(), unsafe {
ffi::PyList_Append(list.as_ptr(), item.as_ptr())
})
}
let py = self.py();
inner(self, item.to_object(py).attach_into(py))
inner(self, item.to_object(py).into_bound(py))
}
/// Inserts an item at the specified index.
@ -491,14 +493,14 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
where
I: ToPyObject,
{
fn inner(list: &Py2<'_, PyList>, index: usize, item: Py2<'_, PyAny>) -> PyResult<()> {
fn inner(list: &Bound<'_, PyList>, index: usize, item: Bound<'_, PyAny>) -> PyResult<()> {
err::error_on_minusone(list.py(), unsafe {
ffi::PyList_Insert(list.as_ptr(), get_ssize_index(index), item.as_ptr())
})
}
let py = self.py();
inner(self, index, item.to_object(py).attach_into(py))
inner(self, index, item.to_object(py).into_bound(py))
}
/// Determines if self contains `value`.
@ -524,8 +526,8 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
}
/// Returns an iterator over this list's items.
fn iter(&self) -> PyListIterator2<'py> {
PyListIterator2::new(self.clone())
fn iter(&self) -> BoundListIterator<'py> {
BoundListIterator::new(self.clone())
}
/// Sorts the list in-place. Equivalent to the Python expression `l.sort()`.
@ -541,7 +543,7 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
/// 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)`.
fn to_tuple(&self) -> Py2<'py, PyTuple> {
fn to_tuple(&self) -> Bound<'py, PyTuple> {
unsafe {
ffi::PyList_AsTuple(self.as_ptr())
.assume_owned(self.py())
@ -551,14 +553,14 @@ impl<'py> PyListMethods<'py> for Py2<'py, PyList> {
}
/// Used by `PyList::iter()`.
pub struct PyListIterator<'a>(PyListIterator2<'a>);
pub struct PyListIterator<'a>(BoundListIterator<'a>);
impl<'a> Iterator for PyListIterator<'a> {
type Item = &'a PyAny;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(Py2::into_gil_ref)
self.0.next().map(Bound::into_gil_ref)
}
#[inline]
@ -570,7 +572,7 @@ impl<'a> Iterator for PyListIterator<'a> {
impl<'a> DoubleEndedIterator for PyListIterator<'a> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(Py2::into_gil_ref)
self.0.next_back().map(Bound::into_gil_ref)
}
}
@ -592,23 +594,23 @@ impl<'a> IntoIterator for &'a PyList {
}
/// Used by `PyList::iter()`.
pub(crate) struct PyListIterator2<'py> {
list: Py2<'py, PyList>,
pub struct BoundListIterator<'py> {
list: Bound<'py, PyList>,
index: usize,
length: usize,
}
impl<'py> PyListIterator2<'py> {
fn new(list: Py2<'py, PyList>) -> Self {
impl<'py> BoundListIterator<'py> {
fn new(list: Bound<'py, PyList>) -> Self {
let length: usize = list.len();
PyListIterator2 {
BoundListIterator {
list,
index: 0,
length,
}
}
unsafe fn get_item(&self, index: usize) -> Py2<'py, PyAny> {
unsafe fn get_item(&self, index: usize) -> Bound<'py, PyAny> {
#[cfg(any(Py_LIMITED_API, PyPy))]
let item = self.list.get_item(index).expect("list.get failed");
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
@ -617,8 +619,8 @@ impl<'py> PyListIterator2<'py> {
}
}
impl<'py> Iterator for PyListIterator2<'py> {
type Item = Py2<'py, PyAny>;
impl<'py> Iterator for BoundListIterator<'py> {
type Item = Bound<'py, PyAny>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
@ -640,7 +642,7 @@ impl<'py> Iterator for PyListIterator2<'py> {
}
}
impl DoubleEndedIterator for PyListIterator2<'_> {
impl DoubleEndedIterator for BoundListIterator<'_> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
let length = self.length.min(self.list.len());
@ -655,29 +657,29 @@ impl DoubleEndedIterator for PyListIterator2<'_> {
}
}
impl ExactSizeIterator for PyListIterator2<'_> {
impl ExactSizeIterator for BoundListIterator<'_> {
fn len(&self) -> usize {
self.length.saturating_sub(self.index)
}
}
impl FusedIterator for PyListIterator2<'_> {}
impl FusedIterator for BoundListIterator<'_> {}
impl<'a, 'py> IntoIterator for &'a Py2<'py, PyList> {
type Item = Py2<'py, PyAny>;
type IntoIter = PyListIterator2<'py>;
impl<'a, 'py> IntoIterator for &'a Bound<'py, PyList> {
type Item = Bound<'py, PyAny>;
type IntoIter = BoundListIterator<'py>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'py> IntoIterator for Py2<'py, PyList> {
type Item = Py2<'py, PyAny>;
type IntoIter = PyListIterator2<'py>;
impl<'py> IntoIterator for Bound<'py, PyList> {
type Item = Bound<'py, PyAny>;
type IntoIter = BoundListIterator<'py>;
fn into_iter(self) -> Self::IntoIter {
PyListIterator2::new(self)
BoundListIterator::new(self)
}
}

View file

@ -1,6 +1,6 @@
use crate::err::{PyDowncastError, PyResult};
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::Py2;
use crate::instance::Bound;
use crate::py_result_ext::PyResultExt;
use crate::sync::GILOnceCell;
use crate::type_object::PyTypeInfo;
@ -20,13 +20,13 @@ impl PyMapping {
/// This is equivalent to the Python expression `len(self)`.
#[inline]
pub fn len(&self) -> PyResult<usize> {
Py2::borrowed_from_gil_ref(&self).len()
Bound::borrowed_from_gil_ref(&self).len()
}
/// Returns whether the mapping is empty.
#[inline]
pub fn is_empty(&self) -> PyResult<bool> {
Py2::borrowed_from_gil_ref(&self).is_empty()
Bound::borrowed_from_gil_ref(&self).is_empty()
}
/// Determines if the mapping contains the specified key.
@ -36,7 +36,7 @@ impl PyMapping {
where
K: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).contains(key)
Bound::borrowed_from_gil_ref(&self).contains(key)
}
/// Gets the item in self with key `key`.
@ -49,9 +49,9 @@ impl PyMapping {
where
K: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.get_item(key)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Sets the item in self with key `key`.
@ -63,7 +63,7 @@ impl PyMapping {
K: ToPyObject,
V: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).set_item(key, value)
Bound::borrowed_from_gil_ref(&self).set_item(key, value)
}
/// Deletes the item with key `key`.
@ -74,31 +74,31 @@ impl PyMapping {
where
K: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).del_item(key)
Bound::borrowed_from_gil_ref(&self).del_item(key)
}
/// Returns a sequence containing all keys in the mapping.
#[inline]
pub fn keys(&self) -> PyResult<&PySequence> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.keys()
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Returns a sequence containing all values in the mapping.
#[inline]
pub fn values(&self) -> PyResult<&PySequence> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.values()
.map(Py2::into_gil_ref)
.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> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.items()
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Register a pyclass as a subclass of `collections.abc.Mapping` (from the Python standard
@ -113,11 +113,11 @@ impl PyMapping {
/// Implementation of functionality for [`PyMapping`].
///
/// These methods are defined for the `Py2<'py, PyMapping>` smart pointer, so to use method call
/// These methods are defined for the `Bound<'py, PyMapping>` smart pointer, so to use method call
/// syntax these methods are separated into a trait, because stable Rust does not yet support
/// `arbitrary_self_types`.
#[doc(alias = "PyMapping")]
pub(crate) trait PyMappingMethods<'py> {
pub trait PyMappingMethods<'py> {
/// Returns the number of objects in the mapping.
///
/// This is equivalent to the Python expression `len(self)`.
@ -138,7 +138,7 @@ pub(crate) trait PyMappingMethods<'py> {
/// Returns an `Err` if the item with specified key is not found, usually `KeyError`.
///
/// This is equivalent to the Python expression `self[key]`.
fn get_item<K>(&self, key: K) -> PyResult<Py2<'py, PyAny>>
fn get_item<K>(&self, key: K) -> PyResult<Bound<'py, PyAny>>
where
K: ToPyObject;
@ -158,16 +158,16 @@ pub(crate) trait PyMappingMethods<'py> {
K: ToPyObject;
/// Returns a sequence containing all keys in the mapping.
fn keys(&self) -> PyResult<Py2<'py, PySequence>>;
fn keys(&self) -> PyResult<Bound<'py, PySequence>>;
/// Returns a sequence containing all values in the mapping.
fn values(&self) -> PyResult<Py2<'py, PySequence>>;
fn values(&self) -> PyResult<Bound<'py, PySequence>>;
/// Returns a sequence of tuples of all (key, value) pairs in the mapping.
fn items(&self) -> PyResult<Py2<'py, PySequence>>;
fn items(&self) -> PyResult<Bound<'py, PySequence>>;
}
impl<'py> PyMappingMethods<'py> for Py2<'py, PyMapping> {
impl<'py> PyMappingMethods<'py> for Bound<'py, PyMapping> {
#[inline]
fn len(&self) -> PyResult<usize> {
let v = unsafe { ffi::PyMapping_Size(self.as_ptr()) };
@ -188,7 +188,7 @@ impl<'py> PyMappingMethods<'py> for Py2<'py, PyMapping> {
}
#[inline]
fn get_item<K>(&self, key: K) -> PyResult<Py2<'py, PyAny>>
fn get_item<K>(&self, key: K) -> PyResult<Bound<'py, PyAny>>
where
K: ToPyObject,
{
@ -213,7 +213,7 @@ impl<'py> PyMappingMethods<'py> for Py2<'py, PyMapping> {
}
#[inline]
fn keys(&self) -> PyResult<Py2<'py, PySequence>> {
fn keys(&self) -> PyResult<Bound<'py, PySequence>> {
unsafe {
ffi::PyMapping_Keys(self.as_ptr())
.assume_owned_or_err(self.py())
@ -222,7 +222,7 @@ impl<'py> PyMappingMethods<'py> for Py2<'py, PyMapping> {
}
#[inline]
fn values(&self) -> PyResult<Py2<'py, PySequence>> {
fn values(&self) -> PyResult<Bound<'py, PySequence>> {
unsafe {
ffi::PyMapping_Values(self.as_ptr())
.assume_owned_or_err(self.py())
@ -231,7 +231,7 @@ impl<'py> PyMappingMethods<'py> for Py2<'py, PyMapping> {
}
#[inline]
fn items(&self) -> PyResult<Py2<'py, PySequence>> {
fn items(&self) -> PyResult<Bound<'py, PySequence>> {
unsafe {
ffi::PyMapping_Items(self.as_ptr())
.assume_owned_or_err(self.py())

View file

@ -76,8 +76,9 @@ pub use self::typeobject::PyType;
/// the Limited API and PyPy, the underlying structures are opaque and that may not be possible.
/// In these cases the iterators are implemented by forwarding to [`PyIterator`].
pub mod iter {
pub use super::dict::PyDictIterator;
pub use super::dict::{BoundDictIterator, PyDictIterator};
pub use super::frozenset::PyFrozenSetIterator;
pub use super::list::{BoundListIterator, PyListIterator};
pub use super::set::PySetIterator;
pub use super::tuple::PyTupleIterator;
}

View file

@ -1,4 +1,4 @@
use crate::instance::Py2;
use crate::instance::Bound;
use crate::types::any::PyAnyMethods;
use crate::types::PyType;
use crate::{ffi, PyTypeInfo};
@ -58,17 +58,17 @@ impl PySuper {
/// ```
pub fn new<'py>(ty: &'py PyType, obj: &'py PyAny) -> PyResult<&'py PySuper> {
Self::new2(
Py2::borrowed_from_gil_ref(&ty),
Py2::borrowed_from_gil_ref(&obj),
Bound::borrowed_from_gil_ref(&ty),
Bound::borrowed_from_gil_ref(&obj),
)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
pub(crate) fn new2<'py>(
ty: &Py2<'py, PyType>,
obj: &Py2<'py, PyAny>,
) -> PyResult<Py2<'py, PySuper>> {
Py2::borrowed_from_gil_ref(&PySuper::type_object(ty.py()))
ty: &Bound<'py, PyType>,
obj: &Bound<'py, PyAny>,
) -> PyResult<Bound<'py, PySuper>> {
Bound::borrowed_from_gil_ref(&PySuper::type_object(ty.py()))
.call1((ty, obj))
.map(|any| {
// Safety: super() always returns instance of super

View file

@ -3,7 +3,7 @@ use crate::exceptions::PyTypeError;
use crate::ffi_ptr_ext::FfiPtrExt;
#[cfg(feature = "experimental-inspect")]
use crate::inspect::types::TypeInfo;
use crate::instance::Py2;
use crate::instance::Bound;
use crate::internal_tricks::get_ssize_index;
use crate::py_result_ext::PyResultExt;
use crate::sync::GILOnceCell;
@ -23,13 +23,13 @@ impl PySequence {
/// This is equivalent to the Python expression `len(self)`.
#[inline]
pub fn len(&self) -> PyResult<usize> {
Py2::borrowed_from_gil_ref(&self).len()
Bound::borrowed_from_gil_ref(&self).len()
}
/// Returns whether the sequence is empty.
#[inline]
pub fn is_empty(&self) -> PyResult<bool> {
Py2::borrowed_from_gil_ref(&self).is_empty()
Bound::borrowed_from_gil_ref(&self).is_empty()
}
/// Returns the concatenation of `self` and `other`.
@ -37,9 +37,9 @@ impl PySequence {
/// This is equivalent to the Python expression `self + other`.
#[inline]
pub fn concat(&self, other: &PySequence) -> PyResult<&PySequence> {
Py2::borrowed_from_gil_ref(&self)
.concat(Py2::borrowed_from_gil_ref(&other))
.map(Py2::into_gil_ref)
Bound::borrowed_from_gil_ref(&self)
.concat(Bound::borrowed_from_gil_ref(&other))
.map(Bound::into_gil_ref)
}
/// Returns the result of repeating a sequence object `count` times.
@ -47,9 +47,9 @@ impl PySequence {
/// This is equivalent to the Python expression `self * count`.
#[inline]
pub fn repeat(&self, count: usize) -> PyResult<&PySequence> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.repeat(count)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Concatenates `self` and `other`, in place if possible.
@ -61,9 +61,9 @@ impl PySequence {
/// possible, but create and return a new object if not.
#[inline]
pub fn in_place_concat(&self, other: &PySequence) -> PyResult<&PySequence> {
Py2::borrowed_from_gil_ref(&self)
.in_place_concat(Py2::borrowed_from_gil_ref(&other))
.map(Py2::into_gil_ref)
Bound::borrowed_from_gil_ref(&self)
.in_place_concat(Bound::borrowed_from_gil_ref(&other))
.map(Bound::into_gil_ref)
}
/// Repeats the sequence object `count` times and updates `self`, if possible.
@ -75,9 +75,9 @@ impl PySequence {
/// possible, but create and return a new object if not.
#[inline]
pub fn in_place_repeat(&self, count: usize) -> PyResult<&PySequence> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.in_place_repeat(count)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Returns the `index`th element of the Sequence.
@ -85,7 +85,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> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.get_item(index)
.map(|py2| py2.into_gil_ref())
}
@ -95,9 +95,9 @@ impl PySequence {
/// This is equivalent to the Python expression `self[begin:end]`.
#[inline]
pub fn get_slice(&self, begin: usize, end: usize) -> PyResult<&PySequence> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.get_slice(begin, end)
.map(Py2::into_gil_ref)
.map(Bound::into_gil_ref)
}
/// Assigns object `item` to the `i`th element of self.
@ -108,7 +108,7 @@ impl PySequence {
where
I: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).set_item(i, item)
Bound::borrowed_from_gil_ref(&self).set_item(i, item)
}
/// Deletes the `i`th element of self.
@ -116,7 +116,7 @@ impl PySequence {
/// This is equivalent to the Python statement `del self[i]`.
#[inline]
pub fn del_item(&self, i: usize) -> PyResult<()> {
Py2::borrowed_from_gil_ref(&self).del_item(i)
Bound::borrowed_from_gil_ref(&self).del_item(i)
}
/// Assigns the sequence `v` to the slice of `self` from `i1` to `i2`.
@ -124,7 +124,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<()> {
Py2::borrowed_from_gil_ref(&self).set_slice(i1, i2, Py2::borrowed_from_gil_ref(&v))
Bound::borrowed_from_gil_ref(&self).set_slice(i1, i2, Bound::borrowed_from_gil_ref(&v))
}
/// Deletes the slice from `i1` to `i2` from `self`.
@ -132,7 +132,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<()> {
Py2::borrowed_from_gil_ref(&self).del_slice(i1, i2)
Bound::borrowed_from_gil_ref(&self).del_slice(i1, i2)
}
/// Returns the number of occurrences of `value` in self, that is, return the
@ -143,7 +143,7 @@ impl PySequence {
where
V: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).count(value)
Bound::borrowed_from_gil_ref(&self).count(value)
}
/// Determines if self contains `value`.
@ -154,7 +154,7 @@ impl PySequence {
where
V: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).contains(value)
Bound::borrowed_from_gil_ref(&self).contains(value)
}
/// Returns the first index `i` for which `self[i] == value`.
@ -165,13 +165,13 @@ impl PySequence {
where
V: ToPyObject,
{
Py2::borrowed_from_gil_ref(&self).index(value)
Bound::borrowed_from_gil_ref(&self).index(value)
}
/// Returns a fresh list based on the Sequence.
#[inline]
pub fn to_list(&self) -> PyResult<&PyList> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.to_list()
.map(|py2| py2.into_gil_ref())
}
@ -179,7 +179,7 @@ impl PySequence {
/// Returns a fresh tuple based on the Sequence.
#[inline]
pub fn to_tuple(&self) -> PyResult<&PyTuple> {
Py2::borrowed_from_gil_ref(&self)
Bound::borrowed_from_gil_ref(&self)
.to_tuple()
.map(|py2| py2.into_gil_ref())
}
@ -196,11 +196,11 @@ impl PySequence {
/// Implementation of functionality for [`PySequence`].
///
/// These methods are defined for the `Py2<'py, PySequence>` smart pointer, so to use method call
/// These methods are defined for the `Bound<'py, PySequence>` smart pointer, so to use method call
/// syntax these methods are separated into a trait, because stable Rust does not yet support
/// `arbitrary_self_types`.
#[doc(alias = "PySequence")]
pub(crate) trait PySequenceMethods<'py> {
pub trait PySequenceMethods<'py> {
/// Returns the number of objects in sequence.
///
/// This is equivalent to the Python expression `len(self)`.
@ -212,12 +212,12 @@ pub(crate) trait PySequenceMethods<'py> {
/// Returns the concatenation of `self` and `other`.
///
/// This is equivalent to the Python expression `self + other`.
fn concat(&self, other: &Py2<'_, PySequence>) -> PyResult<Py2<'py, PySequence>>;
fn concat(&self, other: &Bound<'_, PySequence>) -> PyResult<Bound<'py, PySequence>>;
/// Returns the result of repeating a sequence object `count` times.
///
/// This is equivalent to the Python expression `self * count`.
fn repeat(&self, count: usize) -> PyResult<Py2<'py, PySequence>>;
fn repeat(&self, count: usize) -> PyResult<Bound<'py, PySequence>>;
/// Concatenates `self` and `other`, in place if possible.
///
@ -226,7 +226,7 @@ pub(crate) trait PySequenceMethods<'py> {
/// The Python statement `self += other` is syntactic sugar for `self =
/// self.__iadd__(other)`. `__iadd__` should modify and return `self` if
/// possible, but create and return a new object if not.
fn in_place_concat(&self, other: &Py2<'_, PySequence>) -> PyResult<Py2<'py, PySequence>>;
fn in_place_concat(&self, other: &Bound<'_, PySequence>) -> PyResult<Bound<'py, PySequence>>;
/// Repeats the sequence object `count` times and updates `self`, if possible.
///
@ -235,17 +235,17 @@ pub(crate) trait PySequenceMethods<'py> {
/// The Python statement `self *= other` is syntactic sugar for `self =
/// self.__imul__(other)`. `__imul__` should modify and return `self` if
/// possible, but create and return a new object if not.
fn in_place_repeat(&self, count: usize) -> PyResult<Py2<'py, PySequence>>;
fn in_place_repeat(&self, count: usize) -> PyResult<Bound<'py, PySequence>>;
/// Returns the `index`th element of the Sequence.
///
/// This is equivalent to the Python expression `self[index]` without support of negative indices.
fn get_item(&self, index: usize) -> PyResult<Py2<'py, PyAny>>;
fn get_item(&self, index: usize) -> PyResult<Bound<'py, PyAny>>;
/// Returns the slice of sequence object between `begin` and `end`.
///
/// This is equivalent to the Python expression `self[begin:end]`.
fn get_slice(&self, begin: usize, end: usize) -> PyResult<Py2<'py, PySequence>>;
fn get_slice(&self, begin: usize, end: usize) -> PyResult<Bound<'py, PySequence>>;
/// Assigns object `item` to the `i`th element of self.
///
@ -262,7 +262,7 @@ pub(crate) trait PySequenceMethods<'py> {
/// Assigns the sequence `v` to the slice of `self` from `i1` to `i2`.
///
/// This is equivalent to the Python statement `self[i1:i2] = v`.
fn set_slice(&self, i1: usize, i2: usize, v: &Py2<'_, PyAny>) -> PyResult<()>;
fn set_slice(&self, i1: usize, i2: usize, v: &Bound<'_, PyAny>) -> PyResult<()>;
/// Deletes the slice from `i1` to `i2` from `self`.
///
@ -291,13 +291,13 @@ pub(crate) trait PySequenceMethods<'py> {
V: ToPyObject;
/// Returns a fresh list based on the Sequence.
fn to_list(&self) -> PyResult<Py2<'py, PyList>>;
fn to_list(&self) -> PyResult<Bound<'py, PyList>>;
/// Returns a fresh tuple based on the Sequence.
fn to_tuple(&self) -> PyResult<Py2<'py, PyTuple>>;
fn to_tuple(&self) -> PyResult<Bound<'py, PyTuple>>;
}
impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
impl<'py> PySequenceMethods<'py> for Bound<'py, PySequence> {
#[inline]
fn len(&self) -> PyResult<usize> {
let v = unsafe { ffi::PySequence_Size(self.as_ptr()) };
@ -311,7 +311,7 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
}
#[inline]
fn concat(&self, other: &Py2<'_, PySequence>) -> PyResult<Py2<'py, PySequence>> {
fn concat(&self, other: &Bound<'_, PySequence>) -> PyResult<Bound<'py, PySequence>> {
unsafe {
ffi::PySequence_Concat(self.as_ptr(), other.as_ptr())
.assume_owned_or_err(self.py())
@ -320,7 +320,7 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
}
#[inline]
fn repeat(&self, count: usize) -> PyResult<Py2<'py, PySequence>> {
fn repeat(&self, count: usize) -> PyResult<Bound<'py, PySequence>> {
unsafe {
ffi::PySequence_Repeat(self.as_ptr(), get_ssize_index(count))
.assume_owned_or_err(self.py())
@ -329,7 +329,7 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
}
#[inline]
fn in_place_concat(&self, other: &Py2<'_, PySequence>) -> PyResult<Py2<'py, PySequence>> {
fn in_place_concat(&self, other: &Bound<'_, PySequence>) -> PyResult<Bound<'py, PySequence>> {
unsafe {
ffi::PySequence_InPlaceConcat(self.as_ptr(), other.as_ptr())
.assume_owned_or_err(self.py())
@ -338,7 +338,7 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
}
#[inline]
fn in_place_repeat(&self, count: usize) -> PyResult<Py2<'py, PySequence>> {
fn in_place_repeat(&self, count: usize) -> PyResult<Bound<'py, PySequence>> {
unsafe {
ffi::PySequence_InPlaceRepeat(self.as_ptr(), get_ssize_index(count))
.assume_owned_or_err(self.py())
@ -347,7 +347,7 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
}
#[inline]
fn get_item(&self, index: usize) -> PyResult<Py2<'py, PyAny>> {
fn get_item(&self, index: usize) -> PyResult<Bound<'py, PyAny>> {
unsafe {
ffi::PySequence_GetItem(self.as_ptr(), get_ssize_index(index))
.assume_owned_or_err(self.py())
@ -355,7 +355,7 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
}
#[inline]
fn get_slice(&self, begin: usize, end: usize) -> PyResult<Py2<'py, PySequence>> {
fn get_slice(&self, begin: usize, end: usize) -> PyResult<Bound<'py, PySequence>> {
unsafe {
ffi::PySequence_GetSlice(self.as_ptr(), get_ssize_index(begin), get_ssize_index(end))
.assume_owned_or_err(self.py())
@ -368,14 +368,14 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
where
I: ToPyObject,
{
fn inner(seq: &Py2<'_, PySequence>, i: usize, item: Py2<'_, PyAny>) -> PyResult<()> {
fn inner(seq: &Bound<'_, PySequence>, i: usize, item: Bound<'_, PyAny>) -> PyResult<()> {
err::error_on_minusone(seq.py(), unsafe {
ffi::PySequence_SetItem(seq.as_ptr(), get_ssize_index(i), item.as_ptr())
})
}
let py = self.py();
inner(self, i, item.to_object(py).attach_into(py))
inner(self, i, item.to_object(py).into_bound(py))
}
#[inline]
@ -386,7 +386,7 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
}
#[inline]
fn set_slice(&self, i1: usize, i2: usize, v: &Py2<'_, PyAny>) -> PyResult<()> {
fn set_slice(&self, i1: usize, i2: usize, v: &Bound<'_, PyAny>) -> PyResult<()> {
err::error_on_minusone(self.py(), unsafe {
ffi::PySequence_SetSlice(
self.as_ptr(),
@ -410,14 +410,14 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
where
V: ToPyObject,
{
fn inner(seq: &Py2<'_, PySequence>, value: Py2<'_, PyAny>) -> PyResult<usize> {
fn inner(seq: &Bound<'_, PySequence>, value: Bound<'_, PyAny>) -> PyResult<usize> {
let r = unsafe { ffi::PySequence_Count(seq.as_ptr(), value.as_ptr()) };
crate::err::error_on_minusone(seq.py(), r)?;
Ok(r as usize)
}
let py = self.py();
inner(self, value.to_object(py).attach_into(py))
inner(self, value.to_object(py).into_bound(py))
}
#[inline]
@ -425,7 +425,7 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
where
V: ToPyObject,
{
fn inner(seq: &Py2<'_, PySequence>, value: Py2<'_, PyAny>) -> PyResult<bool> {
fn inner(seq: &Bound<'_, PySequence>, value: Bound<'_, PyAny>) -> PyResult<bool> {
let r = unsafe { ffi::PySequence_Contains(seq.as_ptr(), value.as_ptr()) };
match r {
0 => Ok(false),
@ -435,7 +435,7 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
}
let py = self.py();
inner(self, value.to_object(py).attach_into(py))
inner(self, value.to_object(py).into_bound(py))
}
#[inline]
@ -443,18 +443,18 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
where
V: ToPyObject,
{
fn inner(seq: &Py2<'_, PySequence>, value: Py2<'_, PyAny>) -> PyResult<usize> {
fn inner(seq: &Bound<'_, PySequence>, value: Bound<'_, PyAny>) -> PyResult<usize> {
let r = unsafe { ffi::PySequence_Index(seq.as_ptr(), value.as_ptr()) };
crate::err::error_on_minusone(seq.py(), r)?;
Ok(r as usize)
}
let py = self.py();
inner(self, value.to_object(self.py()).attach_into(py))
inner(self, value.to_object(self.py()).into_bound(py))
}
#[inline]
fn to_list(&self) -> PyResult<Py2<'py, PyList>> {
fn to_list(&self) -> PyResult<Bound<'py, PyList>> {
unsafe {
ffi::PySequence_List(self.as_ptr())
.assume_owned_or_err(self.py())
@ -463,7 +463,7 @@ impl<'py> PySequenceMethods<'py> for Py2<'py, PySequence> {
}
#[inline]
fn to_tuple(&self) -> PyResult<Py2<'py, PyTuple>> {
fn to_tuple(&self) -> PyResult<Bound<'py, PyTuple>> {
unsafe {
ffi::PySequence_Tuple(self.as_ptr())
.assume_owned_or_err(self.py())

View file

@ -1,11 +1,11 @@
#[cfg(not(Py_LIMITED_API))]
use crate::exceptions::PyUnicodeDecodeError;
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::Py2Borrowed;
use crate::instance::Borrowed;
use crate::types::any::PyAnyMethods;
use crate::types::bytes::PyBytesMethods;
use crate::types::PyBytes;
use crate::{ffi, IntoPy, Py, Py2, PyAny, PyResult, Python};
use crate::{ffi, Bound, IntoPy, Py, PyAny, 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)))]
{
Py2Borrowed::from_gil_ref(self).to_str()
Borrowed::from_gil_ref(self).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>> {
Py2Borrowed::from_gil_ref(self).to_cow()
Borrowed::from_gil_ref(self).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> {
Py2Borrowed::from_gil_ref(self).to_string_lossy()
Borrowed::from_gil_ref(self).to_string_lossy()
}
/// Obtains the raw data backing the Python string.
@ -229,17 +229,17 @@ 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<'_>> {
Py2Borrowed::from_gil_ref(self).data()
Borrowed::from_gil_ref(self).data()
}
}
/// Implementation of functionality for [`PyString`].
///
/// These methods are defined for the `Py2<'py, PyString>` smart pointer, so to use method call
/// These methods are defined for the `Bound<'py, PyString>` smart pointer, so to use method call
/// syntax these methods are separated into a trait, because stable Rust does not yet support
/// `arbitrary_self_types`.
#[doc(alias = "PyString")]
pub(crate) trait PyStringMethods<'py> {
pub trait PyStringMethods<'py> {
/// Gets the Python string as a Rust UTF-8 string slice.
///
/// Returns a `UnicodeEncodeError` if the input is not valid unicode
@ -277,27 +277,27 @@ pub(crate) trait PyStringMethods<'py> {
unsafe fn data(&self) -> PyResult<PyStringData<'_>>;
}
impl<'py> PyStringMethods<'py> for Py2<'py, PyString> {
impl<'py> PyStringMethods<'py> for Bound<'py, PyString> {
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
fn to_str(&self) -> PyResult<&str> {
Py2Borrowed::from(self).to_str()
Borrowed::from(self).to_str()
}
fn to_cow(&self) -> PyResult<Cow<'_, str>> {
Py2Borrowed::from(self).to_cow()
Borrowed::from(self).to_cow()
}
fn to_string_lossy(&self) -> Cow<'_, str> {
Py2Borrowed::from(self).to_string_lossy()
Borrowed::from(self).to_string_lossy()
}
#[cfg(not(Py_LIMITED_API))]
unsafe fn data(&self) -> PyResult<PyStringData<'_>> {
Py2Borrowed::from(self).data()
Borrowed::from(self).data()
}
}
impl<'a> Py2Borrowed<'a, '_, PyString> {
impl<'a> Borrowed<'a, '_, PyString> {
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
#[allow(clippy::wrong_self_convention)]
fn to_str(self) -> PyResult<&'a str> {
@ -407,7 +407,7 @@ impl Py<PyString> {
/// the GIL lifetime.
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
pub fn to_str<'a>(&'a self, py: Python<'_>) -> PyResult<&'a str> {
self.attach_borrow(py).to_str()
self.bind_borrowed(py).to_str()
}
/// Converts the `PyString` into a Rust string, avoiding copying when possible.
@ -418,7 +418,7 @@ impl Py<PyString> {
/// Because `str` objects are immutable, the returned slice is independent of
/// the GIL lifetime.
pub fn to_cow<'a>(&'a self, py: Python<'_>) -> PyResult<Cow<'a, str>> {
self.attach_borrow(py).to_cow()
self.bind_borrowed(py).to_cow()
}
/// Converts the `PyString` into a Rust string.
@ -429,17 +429,17 @@ impl Py<PyString> {
/// Because `str` objects are immutable, the returned slice is independent of
/// the GIL lifetime.
pub fn to_string_lossy<'a>(&'a self, py: Python<'_>) -> Cow<'a, str> {
self.attach_borrow(py).to_string_lossy()
self.bind_borrowed(py).to_string_lossy()
}
}
impl IntoPy<Py<PyString>> for Py2<'_, PyString> {
impl IntoPy<Py<PyString>> for Bound<'_, PyString> {
fn into_py(self, _py: Python<'_>) -> Py<PyString> {
self.into()
}
}
impl IntoPy<Py<PyString>> for &Py2<'_, PyString> {
impl IntoPy<Py<PyString>> for &Bound<'_, PyString> {
fn into_py(self, _py: Python<'_>) -> Py<PyString> {
self.clone().into()
}

View file

@ -9,8 +9,8 @@ error[E0277]: the trait bound `PyErr: From<MyError>` is not satisfied
<PyErr as From<PyBorrowMutError>>
<PyErr as From<std::io::Error>>
<PyErr as From<PyDowncastError<'a>>>
<PyErr as From<pyo3::err::PyDowncastError2<'_, '_>>>
<PyErr as From<pyo3::err::PyDowncastIntoError<'_>>>
<PyErr as From<DowncastError<'_, '_>>>
<PyErr as From<DowncastIntoError<'_>>>
<PyErr as From<NulError>>
<PyErr as From<IntoStringError>>
and $N others