Merge pull request #3686 from davidhewitt/bound
make Bound and Borrowed types public API
This commit is contained in:
commit
a115877bba
1
newsfragments/3686.added.md
Normal file
1
newsfragments/3686.added.md
Normal file
|
@ -0,0 +1 @@
|
|||
Add `Bound<T>` and `Borrowed<T>` smart pointers as a new API for accessing Python objects.
|
|
@ -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!(
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
157
src/instance.rs
157
src/instance.rs
|
@ -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");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
293
src/types/any.rs
293
src/types/any.rs
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() }
|
||||
|
|
|
@ -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() }
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue