feature gate APIs using `into_gil_ref` (Part 1) (#4160)

This commit is contained in:
Icxolu 2024-05-09 09:58:44 +02:00 committed by GitHub
parent d803f7f8df
commit 635cb8075c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 339 additions and 256 deletions

View File

@ -186,11 +186,11 @@ mod tests {
Python::with_gil(|py| {
let array: [f32; 4] = [0.0, -16.0, 16.0, 42.0];
let pyobject = array.to_object(py);
let pylist: &PyList = pyobject.extract(py).unwrap();
assert_eq!(pylist[0].extract::<f32>().unwrap(), 0.0);
assert_eq!(pylist[1].extract::<f32>().unwrap(), -16.0);
assert_eq!(pylist[2].extract::<f32>().unwrap(), 16.0);
assert_eq!(pylist[3].extract::<f32>().unwrap(), 42.0);
let pylist = pyobject.downcast_bound::<PyList>(py).unwrap();
assert_eq!(pylist.get_item(0).unwrap().extract::<f32>().unwrap(), 0.0);
assert_eq!(pylist.get_item(1).unwrap().extract::<f32>().unwrap(), -16.0);
assert_eq!(pylist.get_item(2).unwrap().extract::<f32>().unwrap(), 16.0);
assert_eq!(pylist.get_item(3).unwrap().extract::<f32>().unwrap(), 42.0);
});
}
@ -213,11 +213,11 @@ mod tests {
Python::with_gil(|py| {
let array: [f32; 4] = [0.0, -16.0, 16.0, 42.0];
let pyobject = array.into_py(py);
let pylist: &PyList = pyobject.extract(py).unwrap();
assert_eq!(pylist[0].extract::<f32>().unwrap(), 0.0);
assert_eq!(pylist[1].extract::<f32>().unwrap(), -16.0);
assert_eq!(pylist[2].extract::<f32>().unwrap(), 16.0);
assert_eq!(pylist[3].extract::<f32>().unwrap(), 42.0);
let pylist = pyobject.downcast_bound::<PyList>(py).unwrap();
assert_eq!(pylist.get_item(0).unwrap().extract::<f32>().unwrap(), 0.0);
assert_eq!(pylist.get_item(1).unwrap().extract::<f32>().unwrap(), -16.0);
assert_eq!(pylist.get_item(2).unwrap().extract::<f32>().unwrap(), 16.0);
assert_eq!(pylist.get_item(3).unwrap().extract::<f32>().unwrap(), 42.0);
});
}

View File

@ -667,6 +667,7 @@ impl<'py, T> Borrowed<'py, 'py, T>
where
T: HasPyGilRef,
{
#[cfg(feature = "gil-refs")]
pub(crate) fn into_gil_ref(self) -> &'py T::AsRefTarget {
// Safety: self is a borrow over `'py`.
#[allow(deprecated)]

View File

@ -46,6 +46,7 @@ pub(crate) fn get_ssize_index(index: usize) -> Py_ssize_t {
}
/// Implementations used for slice indexing PySequence, PyTuple, and PyList
#[cfg(feature = "gil-refs")]
macro_rules! index_impls {
(
$ty:ty,
@ -154,6 +155,7 @@ macro_rules! index_impls {
#[inline(never)]
#[cold]
#[track_caller]
#[cfg(feature = "gil-refs")]
pub(crate) fn index_len_fail(index: usize, ty_name: &str, len: usize) -> ! {
panic!(
"index {} out of range for {} of length {}",
@ -164,6 +166,7 @@ pub(crate) fn index_len_fail(index: usize, ty_name: &str, len: usize) -> ! {
#[inline(never)]
#[cold]
#[track_caller]
#[cfg(feature = "gil-refs")]
pub(crate) fn slice_start_index_len_fail(index: usize, ty_name: &str, len: usize) -> ! {
panic!(
"range start index {} out of range for {} of length {}",
@ -174,6 +177,7 @@ pub(crate) fn slice_start_index_len_fail(index: usize, ty_name: &str, len: usize
#[inline(never)]
#[cold]
#[track_caller]
#[cfg(feature = "gil-refs")]
pub(crate) fn slice_end_index_len_fail(index: usize, ty_name: &str, len: usize) -> ! {
panic!(
"range end index {} out of range for {} of length {}",
@ -184,6 +188,7 @@ pub(crate) fn slice_end_index_len_fail(index: usize, ty_name: &str, len: usize)
#[inline(never)]
#[cold]
#[track_caller]
#[cfg(feature = "gil-refs")]
pub(crate) fn slice_index_order_fail(index: usize, end: usize) -> ! {
panic!("slice index starts at {} but ends at {}", index, end);
}

View File

@ -120,8 +120,8 @@ macro_rules! py_run_impl {
/// Wraps a Rust function annotated with [`#[pyfunction]`](macro@crate::pyfunction).
///
/// This can be used with [`PyModule::add_function`](crate::types::PyModule::add_function) to add free
/// functions to a [`PyModule`](crate::types::PyModule) - see its documentation for more
/// This can be used with [`PyModule::add_function`](crate::types::PyModuleMethods::add_function) to
/// add free functions to a [`PyModule`](crate::types::PyModule) - see its documentation for more
/// information.
///
/// During the migration from the GIL Ref API to the Bound API, the return type of this macro will
@ -157,8 +157,9 @@ macro_rules! wrap_pyfunction {
/// Wraps a Rust function annotated with [`#[pyfunction]`](macro@crate::pyfunction).
///
/// This can be used with [`PyModule::add_function`](crate::types::PyModule::add_function) to add free
/// functions to a [`PyModule`](crate::types::PyModule) - see its documentation for more information.
/// This can be used with [`PyModule::add_function`](crate::types::PyModuleMethods::add_function) to
/// add free functions to a [`PyModule`](crate::types::PyModule) - see its documentation for more
/// information.
#[macro_export]
macro_rules! wrap_pyfunction_bound {
($function:path) => {
@ -183,7 +184,7 @@ macro_rules! wrap_pyfunction_bound {
/// Python module.
///
/// Use this together with [`#[pymodule]`](crate::pymodule) and
/// [`PyModule::add_wrapped`](crate::types::PyModule::add_wrapped).
/// [`PyModule::add_wrapped`](crate::types::PyModuleMethods::add_wrapped).
#[macro_export]
macro_rules! wrap_pymodule {
($module:path) => {

View File

@ -114,15 +114,18 @@ mod inner {
}
impl<'py> CatchWarnings<'py> {
pub fn enter<R>(py: Python<'py>, f: impl FnOnce(&PyList) -> PyResult<R>) -> PyResult<R> {
pub fn enter<R>(
py: Python<'py>,
f: impl FnOnce(&Bound<'py, PyList>) -> PyResult<R>,
) -> PyResult<R> {
let warnings = py.import_bound("warnings")?;
let kwargs = [("record", true)].into_py_dict_bound(py);
let catch_warnings = warnings
.getattr("catch_warnings")?
.call((), Some(&kwargs))?;
let list = catch_warnings.call_method0("__enter__")?.extract()?;
let list = catch_warnings.call_method0("__enter__")?.downcast_into()?;
let _guard = Self { catch_warnings };
f(list)
f(&list)
}
}
@ -139,6 +142,7 @@ mod inner {
macro_rules! assert_warnings {
($py:expr, $body:expr, [$(($category:ty, $message:literal)),+] $(,)? ) => {{
$crate::tests::common::CatchWarnings::enter($py, |w| {
use $crate::types::{PyListMethods, PyStringMethods};
$body;
let expected_warnings = [$((<$category as $crate::type_object::PyTypeInfo>::type_object_bound($py), $message)),+];
assert_eq!(w.len(), expected_warnings.len());

View File

@ -14,6 +14,7 @@ fn foo(_py: crate::Python<'_>, _m: &crate::types::PyModule) -> crate::PyResult<(
::std::result::Result::Ok(())
}
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
#[crate::pymodule]
#[pyo3(crate = "crate")]

View File

@ -491,6 +491,7 @@ impl<'a> Borrowed<'a, '_, PyByteArray> {
}
}
#[cfg(feature = "gil-refs")]
impl<'py> TryFrom<&'py PyAny> for &'py PyByteArray {
type Error = crate::PyErr;

View File

@ -59,6 +59,7 @@ mod not_limited_impls {
use super::*;
use std::ops::{Add, Div, Mul, Neg, Sub};
#[cfg(feature = "gil-refs")]
impl PyComplex {
/// Returns `|self|`.
pub fn abs(&self) -> c_double {
@ -94,6 +95,7 @@ mod not_limited_impls {
}
}
#[cfg(feature = "gil-refs")]
impl<'py> $trait for &'py PyComplex {
type Output = &'py PyComplex;
fn $fn(self, other: &'py PyComplex) -> &'py PyComplex {
@ -136,6 +138,7 @@ mod not_limited_impls {
bin_ops!(Mul, mul, *, ffi::_Py_c_prod);
bin_ops!(Div, div, /, ffi::_Py_c_quot);
#[cfg(feature = "gil-refs")]
impl<'py> Neg for &'py PyComplex {
type Output = &'py PyComplex;
fn neg(self) -> &'py PyComplex {

View File

@ -6,7 +6,9 @@ use crate::instance::{Borrowed, Bound};
use crate::py_result_ext::PyResultExt;
use crate::types::any::PyAnyMethods;
use crate::types::{PyAny, PyList};
use crate::{ffi, PyNativeType, Python, ToPyObject};
#[cfg(feature = "gil-refs")]
use crate::PyNativeType;
use crate::{ffi, Python, ToPyObject};
/// Represents a Python `dict`.
#[repr(transparent)]
@ -56,34 +58,11 @@ pyobject_native_type_core!(
);
impl PyDict {
/// Deprecated form of [`new_bound`][PyDict::new_bound].
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyDict::new` will be replaced by `PyDict::new_bound` in a future PyO3 version"
)]
#[inline]
pub fn new(py: Python<'_>) -> &PyDict {
Self::new_bound(py).into_gil_ref()
}
/// Creates a new empty dictionary.
pub fn new_bound(py: Python<'_>) -> Bound<'_, PyDict> {
unsafe { ffi::PyDict_New().assume_owned(py).downcast_into_unchecked() }
}
/// Deprecated form of [`from_sequence_bound`][PyDict::from_sequence_bound].
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyDict::from_sequence` will be replaced by `PyDict::from_sequence_bound` in a future PyO3 version"
)]
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub fn from_sequence(seq: &PyAny) -> PyResult<&PyDict> {
Self::from_sequence_bound(&seq.as_borrowed()).map(Bound::into_gil_ref)
}
/// Creates a new dictionary from the sequence given.
///
/// The sequence must consist of `(PyObject, PyObject)`. This is
@ -100,6 +79,30 @@ impl PyDict {
})?;
Ok(dict)
}
}
#[cfg(feature = "gil-refs")]
impl PyDict {
/// Deprecated form of [`new_bound`][PyDict::new_bound].
#[deprecated(
since = "0.21.0",
note = "`PyDict::new` will be replaced by `PyDict::new_bound` in a future PyO3 version"
)]
#[inline]
pub fn new(py: Python<'_>) -> &PyDict {
Self::new_bound(py).into_gil_ref()
}
/// Deprecated form of [`from_sequence_bound`][PyDict::from_sequence_bound].
#[deprecated(
since = "0.21.0",
note = "`PyDict::from_sequence` will be replaced by `PyDict::from_sequence_bound` in a future PyO3 version"
)]
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub fn from_sequence(seq: &PyAny) -> PyResult<&PyDict> {
Self::from_sequence_bound(&seq.as_borrowed()).map(Bound::into_gil_ref)
}
/// Returns a new dictionary that contains the same key-value pairs as self.
///
@ -550,8 +553,10 @@ fn dict_len(dict: &Bound<'_, PyDict>) -> Py_ssize_t {
}
/// PyO3 implementation of an iterator for a Python `dict` object.
#[cfg(feature = "gil-refs")]
pub struct PyDictIterator<'py>(BoundDictIterator<'py>);
#[cfg(feature = "gil-refs")]
impl<'py> Iterator for PyDictIterator<'py> {
type Item = (&'py PyAny, &'py PyAny);
@ -567,12 +572,14 @@ impl<'py> Iterator for PyDictIterator<'py> {
}
}
#[cfg(feature = "gil-refs")]
impl<'py> ExactSizeIterator for PyDictIterator<'py> {
fn len(&self) -> usize {
self.0.len()
}
}
#[cfg(feature = "gil-refs")]
impl<'a> IntoIterator for &'a PyDict {
type Item = (&'a PyAny, &'a PyAny);
type IntoIter = PyDictIterator<'a>;

View File

@ -1,11 +1,13 @@
use crate::types::PyIterator;
#[cfg(feature = "gil-refs")]
use crate::PyNativeType;
use crate::{
err::{self, PyErr, PyResult},
ffi,
ffi_ptr_ext::FfiPtrExt,
py_result_ext::PyResultExt,
types::any::PyAnyMethods,
Bound, PyAny, PyNativeType, PyObject, Python, ToPyObject,
Bound, PyAny, PyObject, Python, ToPyObject,
};
use std::ptr;
@ -74,20 +76,6 @@ pyobject_native_type_core!(
);
impl PyFrozenSet {
/// Deprecated form of [`PyFrozenSet::new_bound`].
#[inline]
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyFrozenSet::new` will be replaced by `PyFrozenSet::new_bound` in a future PyO3 version"
)]
pub fn new<'a, 'p, T: ToPyObject + 'a>(
py: Python<'p>,
elements: impl IntoIterator<Item = &'a T>,
) -> PyResult<&'p PyFrozenSet> {
Self::new_bound(py, elements).map(Bound::into_gil_ref)
}
/// Creates a new frozenset.
///
/// May panic when running out of memory.
@ -99,16 +87,6 @@ impl PyFrozenSet {
new_from_iter(py, elements)
}
/// Deprecated form of [`PyFrozenSet::empty_bound`].
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyFrozenSet::empty` will be replaced by `PyFrozenSet::empty_bound` in a future PyO3 version"
)]
pub fn empty(py: Python<'_>) -> PyResult<&'_ PyFrozenSet> {
Self::empty_bound(py).map(Bound::into_gil_ref)
}
/// Creates a new empty frozen set
pub fn empty_bound(py: Python<'_>) -> PyResult<Bound<'_, PyFrozenSet>> {
unsafe {
@ -117,6 +95,31 @@ impl PyFrozenSet {
.downcast_into_unchecked()
}
}
}
#[cfg(feature = "gil-refs")]
impl PyFrozenSet {
/// Deprecated form of [`PyFrozenSet::new_bound`].
#[inline]
#[deprecated(
since = "0.21.0",
note = "`PyFrozenSet::new` will be replaced by `PyFrozenSet::new_bound` in a future PyO3 version"
)]
pub fn new<'a, 'p, T: ToPyObject + 'a>(
py: Python<'p>,
elements: impl IntoIterator<Item = &'a T>,
) -> PyResult<&'p PyFrozenSet> {
Self::new_bound(py, elements).map(Bound::into_gil_ref)
}
/// Deprecated form of [`PyFrozenSet::empty_bound`].
#[deprecated(
since = "0.21.0",
note = "`PyFrozenSet::empty` will be replaced by `PyFrozenSet::empty_bound` in a future PyO3 version"
)]
pub fn empty(py: Python<'_>) -> PyResult<&'_ PyFrozenSet> {
Self::empty_bound(py).map(Bound::into_gil_ref)
}
/// Return the number of items in the set.
/// This is equivalent to len(p) on a set.
@ -201,8 +204,10 @@ impl<'py> PyFrozenSetMethods<'py> for Bound<'py, PyFrozenSet> {
}
/// PyO3 implementation of an iterator for a Python `frozenset` object.
#[cfg(feature = "gil-refs")]
pub struct PyFrozenSetIterator<'py>(BoundFrozenSetIterator<'py>);
#[cfg(feature = "gil-refs")]
impl<'py> Iterator for PyFrozenSetIterator<'py> {
type Item = &'py super::PyAny;
@ -217,6 +222,7 @@ impl<'py> Iterator for PyFrozenSetIterator<'py> {
}
}
#[cfg(feature = "gil-refs")]
impl ExactSizeIterator for PyFrozenSetIterator<'_> {
#[inline]
fn len(&self) -> usize {
@ -224,6 +230,7 @@ impl ExactSizeIterator for PyFrozenSetIterator<'_> {
}
}
#[cfg(feature = "gil-refs")]
impl<'py> IntoIterator for &'py PyFrozenSet {
type Item = &'py PyAny;
type IntoIter = PyFrozenSetIterator<'py>;

View File

@ -1,9 +1,9 @@
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::Borrowed;
use crate::py_result_ext::PyResultExt;
use crate::{ffi, AsPyPointer, Bound, PyAny, PyErr, PyResult, PyTypeCheck};
#[cfg(feature = "gil-refs")]
use crate::PyDowncastError;
use crate::{ffi, AsPyPointer, Bound, PyAny, PyErr, PyNativeType, PyResult, PyTypeCheck};
use crate::{PyDowncastError, PyNativeType};
/// A Python iterator object.
///
@ -54,6 +54,7 @@ impl PyIterator {
}
}
#[cfg(feature = "gil-refs")]
impl<'p> Iterator for &'p PyIterator {
type Item = PyResult<&'p PyAny>;

View File

@ -6,7 +6,9 @@ use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::Borrowed;
use crate::internal_tricks::get_ssize_index;
use crate::types::{PySequence, PyTuple};
use crate::{Bound, PyAny, PyNativeType, PyObject, Python, ToPyObject};
#[cfg(feature = "gil-refs")]
use crate::PyNativeType;
use crate::{Bound, PyAny, PyObject, Python, ToPyObject};
use crate::types::any::PyAnyMethods;
use crate::types::sequence::PySequenceMethods;
@ -55,26 +57,10 @@ pub(crate) fn new_from_iter<'py>(
}
impl PyList {
/// Deprecated form of [`PyList::new_bound`].
#[inline]
#[track_caller]
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyList::new` will be replaced by `PyList::new_bound` in a future PyO3 version"
)]
pub fn new<T, U>(py: Python<'_>, elements: impl IntoIterator<Item = T, IntoIter = U>) -> &PyList
where
T: ToPyObject,
U: ExactSizeIterator<Item = T>,
{
Self::new_bound(py, elements).into_gil_ref()
}
/// Constructs a new list with the given elements.
///
/// If you want to create a [`PyList`] with elements of different or unknown types, or from an
/// iterable that doesn't implement [`ExactSizeIterator`], use [`PyList::append`].
/// iterable that doesn't implement [`ExactSizeIterator`], use [`PyListMethods::append`].
///
/// # Examples
///
@ -109,17 +95,6 @@ impl PyList {
new_from_iter(py, &mut iter)
}
/// Deprecated form of [`PyList::empty_bound`].
#[inline]
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyList::empty` will be replaced by `PyList::empty_bound` in a future PyO3 version"
)]
pub fn empty(py: Python<'_>) -> &PyList {
Self::empty_bound(py).into_gil_ref()
}
/// Constructs a new empty list.
pub fn empty_bound(py: Python<'_>) -> Bound<'_, PyList> {
unsafe {
@ -128,6 +103,34 @@ impl PyList {
.downcast_into_unchecked()
}
}
}
#[cfg(feature = "gil-refs")]
impl PyList {
/// Deprecated form of [`PyList::new_bound`].
#[inline]
#[track_caller]
#[deprecated(
since = "0.21.0",
note = "`PyList::new` will be replaced by `PyList::new_bound` in a future PyO3 version"
)]
pub fn new<T, U>(py: Python<'_>, elements: impl IntoIterator<Item = T, IntoIter = U>) -> &PyList
where
T: ToPyObject,
U: ExactSizeIterator<Item = T>,
{
Self::new_bound(py, elements).into_gil_ref()
}
/// Deprecated form of [`PyList::empty_bound`].
#[inline]
#[deprecated(
since = "0.21.0",
note = "`PyList::empty` will be replaced by `PyList::empty_bound` in a future PyO3 version"
)]
pub fn empty(py: Python<'_>) -> &PyList {
Self::empty_bound(py).into_gil_ref()
}
/// Returns the length of the list.
pub fn len(&self) -> usize {
@ -273,6 +276,7 @@ impl PyList {
}
}
#[cfg(feature = "gil-refs")]
index_impls!(PyList, "list", PyList::len, PyList::get_slice);
/// Implementation of functionality for [`PyList`].
@ -586,8 +590,10 @@ impl<'py> PyListMethods<'py> for Bound<'py, PyList> {
}
/// Used by `PyList::iter()`.
#[cfg(feature = "gil-refs")]
pub struct PyListIterator<'a>(BoundListIterator<'a>);
#[cfg(feature = "gil-refs")]
impl<'a> Iterator for PyListIterator<'a> {
type Item = &'a PyAny;
@ -602,6 +608,7 @@ impl<'a> Iterator for PyListIterator<'a> {
}
}
#[cfg(feature = "gil-refs")]
impl<'a> DoubleEndedIterator for PyListIterator<'a> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
@ -609,14 +616,17 @@ impl<'a> DoubleEndedIterator for PyListIterator<'a> {
}
}
#[cfg(feature = "gil-refs")]
impl<'a> ExactSizeIterator for PyListIterator<'a> {
fn len(&self) -> usize {
self.0.len()
}
}
#[cfg(feature = "gil-refs")]
impl FusedIterator for PyListIterator<'_> {}
#[cfg(feature = "gil-refs")]
impl<'a> IntoIterator for &'a PyList {
type Item = &'a PyAny;
type IntoIter = PyListIterator<'a>;

View File

@ -1,4 +1,4 @@
use crate::err::{PyDowncastError, PyResult};
use crate::err::PyResult;
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::Bound;
use crate::py_result_ext::PyResultExt;
@ -6,7 +6,9 @@ use crate::sync::GILOnceCell;
use crate::type_object::PyTypeInfo;
use crate::types::any::PyAnyMethods;
use crate::types::{PyAny, PyDict, PySequence, PyType};
use crate::{ffi, Py, PyNativeType, PyTypeCheck, Python, ToPyObject};
#[cfg(feature = "gil-refs")]
use crate::{err::PyDowncastError, PyNativeType};
use crate::{ffi, Py, PyTypeCheck, Python, ToPyObject};
/// Represents a reference to a Python object supporting the mapping protocol.
#[repr(transparent)]
@ -14,6 +16,18 @@ pub struct PyMapping(PyAny);
pyobject_native_type_named!(PyMapping);
pyobject_native_type_extract!(PyMapping);
impl PyMapping {
/// Register a pyclass as a subclass of `collections.abc.Mapping` (from the Python standard
/// library). This is equivalent to `collections.abc.Mapping.register(T)` in Python.
/// This registration is required for a pyclass to be downcastable from `PyAny` to `PyMapping`.
pub fn register<T: PyTypeInfo>(py: Python<'_>) -> PyResult<()> {
let ty = T::type_object_bound(py);
get_mapping_abc(py)?.call_method1("register", (ty,))?;
Ok(())
}
}
#[cfg(feature = "gil-refs")]
impl PyMapping {
/// Returns the number of objects in the mapping.
///
@ -92,15 +106,6 @@ impl PyMapping {
pub fn items(&self) -> PyResult<&PySequence> {
self.as_borrowed().items().map(Bound::into_gil_ref)
}
/// Register a pyclass as a subclass of `collections.abc.Mapping` (from the Python standard
/// library). This is equvalent to `collections.abc.Mapping.register(T)` in Python.
/// This registration is required for a pyclass to be downcastable from `PyAny` to `PyMapping`.
pub fn register<T: PyTypeInfo>(py: Python<'_>) -> PyResult<()> {
let ty = T::type_object_bound(py);
get_mapping_abc(py)?.call_method1("register", (ty,))?;
Ok(())
}
}
/// Implementation of functionality for [`PyMapping`].
@ -255,6 +260,7 @@ impl PyTypeCheck for PyMapping {
}
}
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
impl<'v> crate::PyTryFrom<'v> for PyMapping {
/// Downcasting to `PyMapping` requires the concrete class to be a subclass (or registered

View File

@ -1,7 +1,9 @@
use crate::err::PyResult;
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::py_result_ext::PyResultExt;
use crate::{ffi, AsPyPointer, Bound, PyAny, PyNativeType};
#[cfg(feature = "gil-refs")]
use crate::PyNativeType;
use crate::{ffi, AsPyPointer, Bound, PyAny};
/// Represents a Python `memoryview`.
#[repr(transparent)]
@ -31,6 +33,7 @@ impl PyMemoryView {
}
}
#[cfg(feature = "gil-refs")]
impl<'py> TryFrom<&'py PyAny> for &'py PyMemoryView {
type Error = crate::PyErr;

View File

@ -79,11 +79,17 @@ pub use self::typeobject::{PyType, PyTypeMethods};
/// 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::{BoundDictIterator, PyDictIterator};
pub use super::frozenset::{BoundFrozenSetIterator, PyFrozenSetIterator};
pub use super::list::{BoundListIterator, PyListIterator};
pub use super::set::{BoundSetIterator, PySetIterator};
pub use super::tuple::{BorrowedTupleIterator, BoundTupleIterator, PyTupleIterator};
pub use super::dict::BoundDictIterator;
pub use super::frozenset::BoundFrozenSetIterator;
pub use super::list::BoundListIterator;
pub use super::set::BoundSetIterator;
pub use super::tuple::{BorrowedTupleIterator, BoundTupleIterator};
#[cfg(feature = "gil-refs")]
pub use super::{
dict::PyDictIterator, frozenset::PyFrozenSetIterator, list::PyListIterator,
set::PySetIterator, tuple::PyTupleIterator,
};
}
/// Python objects that have a base type.

View File

@ -6,11 +6,12 @@ use crate::pyclass::PyClass;
use crate::types::{
any::PyAnyMethods, list::PyListMethods, PyAny, PyCFunction, PyDict, PyList, PyString,
};
use crate::{exceptions, ffi, Bound, IntoPy, Py, PyNativeType, PyObject, Python};
use crate::{exceptions, ffi, Bound, IntoPy, Py, PyObject, Python};
use std::ffi::CString;
use std::str;
use super::PyStringMethods;
#[cfg(feature = "gil-refs")]
use {super::PyStringMethods, crate::PyNativeType};
/// Represents a Python [`module`][1] object.
///
@ -25,17 +26,6 @@ pub struct PyModule(PyAny);
pyobject_native_type_core!(PyModule, pyobject_native_static_type_object!(ffi::PyModule_Type), #checkfunction=ffi::PyModule_Check);
impl PyModule {
/// Deprecated form of [`PyModule::new_bound`].
#[inline]
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyModule::new` will be replaced by `PyModule::new_bound` in a future PyO3 version"
)]
pub fn new<'py>(py: Python<'py>, name: &str) -> PyResult<&'py PyModule> {
Self::new_bound(py, name).map(Bound::into_gil_ref)
}
/// Creates a new module object with the `__name__` attribute set to `name`.
///
/// # Examples
@ -62,20 +52,6 @@ impl PyModule {
}
}
/// Deprecated form of [`PyModule::import_bound`].
#[inline]
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyModule::import` will be replaced by `PyModule::import_bound` in a future PyO3 version"
)]
pub fn import<N>(py: Python<'_>, name: N) -> PyResult<&PyModule>
where
N: IntoPy<Py<PyString>>,
{
Self::import_bound(py, name).map(Bound::into_gil_ref)
}
/// Imports the Python module with the specified name.
///
/// # Examples
@ -106,22 +82,6 @@ impl PyModule {
}
}
/// Deprecated form of [`PyModule::from_code_bound`].
#[inline]
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyModule::from_code` will be replaced by `PyModule::from_code_bound` in a future PyO3 version"
)]
pub fn from_code<'py>(
py: Python<'py>,
code: &str,
file_name: &str,
module_name: &str,
) -> PyResult<&'py PyModule> {
Self::from_code_bound(py, code, file_name, module_name).map(Bound::into_gil_ref)
}
/// Creates and loads a module named `module_name`,
/// containing the Python code passed to `code`
/// and pretending to live at `file_name`.
@ -195,6 +155,47 @@ impl PyModule {
.downcast_into()
}
}
}
#[cfg(feature = "gil-refs")]
impl PyModule {
/// Deprecated form of [`PyModule::new_bound`].
#[inline]
#[deprecated(
since = "0.21.0",
note = "`PyModule::new` will be replaced by `PyModule::new_bound` in a future PyO3 version"
)]
pub fn new<'py>(py: Python<'py>, name: &str) -> PyResult<&'py PyModule> {
Self::new_bound(py, name).map(Bound::into_gil_ref)
}
/// Deprecated form of [`PyModule::import_bound`].
#[inline]
#[deprecated(
since = "0.21.0",
note = "`PyModule::import` will be replaced by `PyModule::import_bound` in a future PyO3 version"
)]
pub fn import<N>(py: Python<'_>, name: N) -> PyResult<&PyModule>
where
N: IntoPy<Py<PyString>>,
{
Self::import_bound(py, name).map(Bound::into_gil_ref)
}
/// Deprecated form of [`PyModule::from_code_bound`].
#[inline]
#[deprecated(
since = "0.21.0",
note = "`PyModule::from_code` will be replaced by `PyModule::from_code_bound` in a future PyO3 version"
)]
pub fn from_code<'py>(
py: Python<'py>,
code: &str,
file_name: &str,
module_name: &str,
) -> PyResult<&'py PyModule> {
Self::from_code_bound(py, code, file_name, module_name).map(Bound::into_gil_ref)
}
/// Returns the module's `__dict__` attribute, which contains the module's symbol table.
pub fn dict(&self) -> &PyDict {
@ -433,8 +434,9 @@ pub trait PyModuleMethods<'py>: crate::sealed::Sealed {
/// Adds an attribute to the module.
///
/// For adding classes, functions or modules, prefer to use [`PyModule::add_class`],
/// [`PyModule::add_function`] or [`PyModule::add_submodule`] instead, respectively.
/// For adding classes, functions or modules, prefer to use [`PyModuleMethods::add_class`],
/// [`PyModuleMethods::add_function`] or [`PyModuleMethods::add_submodule`] instead,
/// respectively.
///
/// # Examples
///
@ -510,7 +512,8 @@ pub trait PyModuleMethods<'py>: crate::sealed::Sealed {
/// Adds a function or a (sub)module to a module, using the functions name as name.
///
/// Prefer to use [`PyModule::add_function`] and/or [`PyModule::add_submodule`] instead.
/// Prefer to use [`PyModuleMethods::add_function`] and/or [`PyModuleMethods::add_submodule`]
/// instead.
fn add_wrapped<T>(&self, wrapper: &impl Fn(Python<'py>) -> T) -> PyResult<()>
where
T: IntoPyCallbackOutput<PyObject>;

View File

@ -1,4 +1,4 @@
use crate::err::{self, DowncastError, PyDowncastError, PyErr, PyResult};
use crate::err::{self, DowncastError, PyErr, PyResult};
use crate::exceptions::PyTypeError;
use crate::ffi_ptr_ext::FfiPtrExt;
#[cfg(feature = "experimental-inspect")]
@ -9,7 +9,9 @@ use crate::py_result_ext::PyResultExt;
use crate::sync::GILOnceCell;
use crate::type_object::PyTypeInfo;
use crate::types::{any::PyAnyMethods, PyAny, PyList, PyString, PyTuple, PyType};
use crate::{ffi, FromPyObject, Py, PyNativeType, PyTypeCheck, Python, ToPyObject};
#[cfg(feature = "gil-refs")]
use crate::{err::PyDowncastError, PyNativeType};
use crate::{ffi, FromPyObject, Py, PyTypeCheck, Python, ToPyObject};
/// Represents a reference to a Python object supporting the sequence protocol.
#[repr(transparent)]
@ -17,6 +19,18 @@ pub struct PySequence(PyAny);
pyobject_native_type_named!(PySequence);
pyobject_native_type_extract!(PySequence);
impl PySequence {
/// Register a pyclass as a subclass of `collections.abc.Sequence` (from the Python standard
/// library). This is equivalent to `collections.abc.Sequence.register(T)` in Python.
/// This registration is required for a pyclass to be downcastable from `PyAny` to `PySequence`.
pub fn register<T: PyTypeInfo>(py: Python<'_>) -> PyResult<()> {
let ty = T::type_object_bound(py);
get_sequence_abc(py)?.call_method1("register", (ty,))?;
Ok(())
}
}
#[cfg(feature = "gil-refs")]
impl PySequence {
/// Returns the number of objects in sequence.
///
@ -175,15 +189,6 @@ impl PySequence {
pub fn to_tuple(&self) -> PyResult<&PyTuple> {
self.as_borrowed().to_tuple().map(Bound::into_gil_ref)
}
/// Register a pyclass as a subclass of `collections.abc.Sequence` (from the Python standard
/// library). This is equvalent to `collections.abc.Sequence.register(T)` in Python.
/// This registration is required for a pyclass to be downcastable from `PyAny` to `PySequence`.
pub fn register<T: PyTypeInfo>(py: Python<'_>) -> PyResult<()> {
let ty = T::type_object_bound(py);
get_sequence_abc(py)?.call_method1("register", (ty,))?;
Ok(())
}
}
/// Implementation of functionality for [`PySequence`].
@ -465,16 +470,19 @@ impl<'py> PySequenceMethods<'py> for Bound<'py, PySequence> {
}
#[inline]
#[cfg(feature = "gil-refs")]
fn sequence_len(seq: &PySequence) -> usize {
seq.len().expect("failed to get sequence length")
}
#[inline]
#[cfg(feature = "gil-refs")]
fn sequence_slice(seq: &PySequence, start: usize, end: usize) -> &PySequence {
seq.get_slice(start, end)
.expect("sequence slice operation failed")
}
#[cfg(feature = "gil-refs")]
index_impls!(PySequence, "sequence", sequence_len, sequence_slice);
impl<'py, T> FromPyObject<'py> for Vec<T>
@ -539,6 +547,7 @@ impl PyTypeCheck for PySequence {
}
}
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
impl<'v> crate::PyTryFrom<'v> for PySequence {
/// Downcasting to `PySequence` requires the concrete class to be a subclass (or registered

View File

@ -1,11 +1,12 @@
use crate::types::PyIterator;
#[cfg(feature = "gil-refs")]
use crate::PyNativeType;
use crate::{
err::{self, PyErr, PyResult},
ffi_ptr_ext::FfiPtrExt,
instance::Bound,
py_result_ext::PyResultExt,
types::any::PyAnyMethods,
PyNativeType,
};
use crate::{ffi, PyAny, PyObject, Python, ToPyObject};
use std::ptr;
@ -30,8 +31,30 @@ pyobject_native_type_core!(
);
impl PySet {
/// Deprecated form of [`PySet::new_bound`].
/// Creates a new set with elements from the given slice.
///
/// Returns an error if some element is not hashable.
#[inline]
pub fn new_bound<'a, 'p, T: ToPyObject + 'a>(
py: Python<'p>,
elements: impl IntoIterator<Item = &'a T>,
) -> PyResult<Bound<'p, PySet>> {
new_from_iter(py, elements)
}
/// Creates a new empty set.
pub fn empty_bound(py: Python<'_>) -> PyResult<Bound<'_, PySet>> {
unsafe {
ffi::PySet_New(ptr::null_mut())
.assume_owned_or_err(py)
.downcast_into_unchecked()
}
}
}
#[cfg(feature = "gil-refs")]
impl PySet {
/// Deprecated form of [`PySet::new_bound`].
#[deprecated(
since = "0.21.0",
note = "`PySet::new` will be replaced by `PySet::new_bound` in a future PyO3 version"
@ -44,19 +67,7 @@ impl PySet {
Self::new_bound(py, elements).map(Bound::into_gil_ref)
}
/// Creates a new set with elements from the given slice.
///
/// Returns an error if some element is not hashable.
#[inline]
pub fn new_bound<'a, 'p, T: ToPyObject + 'a>(
py: Python<'p>,
elements: impl IntoIterator<Item = &'a T>,
) -> PyResult<Bound<'p, PySet>> {
new_from_iter(py, elements)
}
/// Deprecated form of [`PySet::empty_bound`].
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.2",
note = "`PySet::empty` will be replaced by `PySet::empty_bound` in a future PyO3 version"
@ -65,15 +76,6 @@ impl PySet {
Self::empty_bound(py).map(Bound::into_gil_ref)
}
/// Creates a new empty set.
pub fn empty_bound(py: Python<'_>) -> PyResult<Bound<'_, PySet>> {
unsafe {
ffi::PySet_New(ptr::null_mut())
.assume_owned_or_err(py)
.downcast_into_unchecked()
}
}
/// Removes all elements from the set.
#[inline]
pub fn clear(&self) {
@ -259,8 +261,10 @@ impl<'py> PySetMethods<'py> for Bound<'py, PySet> {
}
/// PyO3 implementation of an iterator for a Python `set` object.
#[cfg(feature = "gil-refs")]
pub struct PySetIterator<'py>(BoundSetIterator<'py>);
#[cfg(feature = "gil-refs")]
impl<'py> Iterator for PySetIterator<'py> {
type Item = &'py super::PyAny;
@ -279,12 +283,14 @@ impl<'py> Iterator for PySetIterator<'py> {
}
}
#[cfg(feature = "gil-refs")]
impl ExactSizeIterator for PySetIterator<'_> {
fn len(&self) -> usize {
self.0.len()
}
}
#[cfg(feature = "gil-refs")]
impl<'py> IntoIterator for &'py PySet {
type Item = &'py PyAny;
type IntoIter = PySetIterator<'py>;

View File

@ -7,9 +7,11 @@ use crate::inspect::types::TypeInfo;
use crate::instance::Borrowed;
use crate::internal_tricks::get_ssize_index;
use crate::types::{any::PyAnyMethods, sequence::PySequenceMethods, PyList, PySequence};
#[cfg(feature = "gil-refs")]
use crate::PyNativeType;
use crate::{
exceptions, Bound, FromPyObject, IntoPy, Py, PyAny, PyErr, PyNativeType, PyObject, PyResult,
Python, ToPyObject,
exceptions, Bound, FromPyObject, IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python,
ToPyObject,
};
#[inline]
@ -57,24 +59,6 @@ pub struct PyTuple(PyAny);
pyobject_native_type_core!(PyTuple, pyobject_native_static_type_object!(ffi::PyTuple_Type), #checkfunction=ffi::PyTuple_Check);
impl PyTuple {
/// Deprecated form of `PyTuple::new_bound`.
#[track_caller]
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyTuple::new` will be replaced by `PyTuple::new_bound` in a future PyO3 version"
)]
pub fn new<T, U>(
py: Python<'_>,
elements: impl IntoIterator<Item = T, IntoIter = U>,
) -> &PyTuple
where
T: ToPyObject,
U: ExactSizeIterator<Item = T>,
{
Self::new_bound(py, elements).into_gil_ref()
}
/// Constructs a new tuple with the given elements.
///
/// If you want to create a [`PyTuple`] with elements of different or unknown types, or from an
@ -114,16 +98,6 @@ impl PyTuple {
new_from_iter(py, &mut elements)
}
/// Deprecated form of `PyTuple::empty_bound`.
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyTuple::empty` will be replaced by `PyTuple::empty_bound` in a future PyO3 version"
)]
pub fn empty(py: Python<'_>) -> &PyTuple {
Self::empty_bound(py).into_gil_ref()
}
/// Constructs an empty tuple (on the Python side, a singleton object).
pub fn empty_bound(py: Python<'_>) -> Bound<'_, PyTuple> {
unsafe {
@ -132,6 +106,35 @@ impl PyTuple {
.downcast_into_unchecked()
}
}
}
#[cfg(feature = "gil-refs")]
impl PyTuple {
/// Deprecated form of `PyTuple::new_bound`.
#[track_caller]
#[deprecated(
since = "0.21.0",
note = "`PyTuple::new` will be replaced by `PyTuple::new_bound` in a future PyO3 version"
)]
pub fn new<T, U>(
py: Python<'_>,
elements: impl IntoIterator<Item = T, IntoIter = U>,
) -> &PyTuple
where
T: ToPyObject,
U: ExactSizeIterator<Item = T>,
{
Self::new_bound(py, elements).into_gil_ref()
}
/// Deprecated form of `PyTuple::empty_bound`.
#[deprecated(
since = "0.21.0",
note = "`PyTuple::empty` will be replaced by `PyTuple::empty_bound` in a future PyO3 version"
)]
pub fn empty(py: Python<'_>) -> &PyTuple {
Self::empty_bound(py).into_gil_ref()
}
/// Gets the length of the tuple.
pub fn len(&self) -> usize {
@ -236,6 +239,7 @@ impl PyTuple {
}
}
#[cfg(feature = "gil-refs")]
index_impls!(PyTuple, "tuple", PyTuple::len, PyTuple::get_slice);
/// Implementation of functionality for [`PyTuple`].
@ -443,8 +447,10 @@ impl<'a, 'py> Borrowed<'a, 'py, PyTuple> {
}
/// Used by `PyTuple::iter()`.
#[cfg(feature = "gil-refs")]
pub struct PyTupleIterator<'a>(BorrowedTupleIterator<'a, 'a>);
#[cfg(feature = "gil-refs")]
impl<'a> Iterator for PyTupleIterator<'a> {
type Item = &'a PyAny;
@ -459,6 +465,7 @@ impl<'a> Iterator for PyTupleIterator<'a> {
}
}
#[cfg(feature = "gil-refs")]
impl<'a> DoubleEndedIterator for PyTupleIterator<'a> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
@ -466,14 +473,17 @@ impl<'a> DoubleEndedIterator for PyTupleIterator<'a> {
}
}
#[cfg(feature = "gil-refs")]
impl<'a> ExactSizeIterator for PyTupleIterator<'a> {
fn len(&self) -> usize {
self.0.len()
}
}
#[cfg(feature = "gil-refs")]
impl FusedIterator for PyTupleIterator<'_> {}
#[cfg(feature = "gil-refs")]
impl<'a> IntoIterator for &'a PyTuple {
type Item = &'a PyAny;
type IntoIter = PyTupleIterator<'a>;

View File

@ -10,6 +10,7 @@ fn basic_function(py: pyo3::Python<'_>, x: Option<pyo3::PyObject>) -> pyo3::PyOb
x.unwrap_or_else(|| py.None())
}
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
#[pyo3::pymodule]
fn basic_module(_py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> {
@ -108,7 +109,7 @@ impl BasicClass {
#[test]
fn test_basic() {
pyo3::Python::with_gil(|py| {
let module = pyo3::wrap_pymodule!(basic_module)(py);
let module = pyo3::wrap_pymodule!(basic_module_bound)(py);
let cls = py.get_type_bound::<BasicClass>();
let d = pyo3::types::IntoPyDict::into_py_dict_bound(
[

View File

@ -58,8 +58,8 @@ fn pyfunction_with_module<'py>(module: &Bound<'py, PyModule>) -> PyResult<Bound<
#[pyfunction]
#[pyo3(pass_module)]
fn pyfunction_with_module_gil_ref(module: &PyModule) -> PyResult<&str> {
module.name()
fn pyfunction_with_module_gil_ref(_module: &PyModule) -> PyResult<&str> {
todo!()
}
#[pyfunction]
@ -68,14 +68,12 @@ fn double(x: usize) -> usize {
}
#[pymodule]
fn module_gil_ref(m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(double, m)?)?;
fn module_gil_ref(_m: &PyModule) -> PyResult<()> {
Ok(())
}
#[pymodule]
fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(double, m)?)?;
fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, _m: &PyModule) -> PyResult<()> {
Ok(())
}

View File

@ -53,69 +53,69 @@ error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::function_arg`
| ^
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::function_arg`: use `&Bound<'_, T>` instead for this function argument
--> tests/ui/deprecations.rs:61:43
--> tests/ui/deprecations.rs:61:44
|
61 | fn pyfunction_with_module_gil_ref(module: &PyModule) -> PyResult<&str> {
61 | fn pyfunction_with_module_gil_ref(_module: &PyModule) -> PyResult<&str> {
| ^
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::function_arg`: use `&Bound<'_, T>` instead for this function argument
--> tests/ui/deprecations.rs:71:19
|
71 | fn module_gil_ref(m: &PyModule) -> PyResult<()> {
| ^
71 | fn module_gil_ref(_m: &PyModule) -> PyResult<()> {
| ^^
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::function_arg`: use `&Bound<'_, T>` instead for this function argument
--> tests/ui/deprecations.rs:77:57
--> tests/ui/deprecations.rs:76:57
|
77 | fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
| ^
76 | fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, _m: &PyModule) -> PyResult<()> {
| ^^
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor
--> tests/ui/deprecations.rs:110:27
--> tests/ui/deprecations.rs:108:27
|
110 | #[pyo3(from_py_with = "extract_gil_ref")] _gil_ref: i32,
108 | #[pyo3(from_py_with = "extract_gil_ref")] _gil_ref: i32,
| ^^^^^^^^^^^^^^^^^
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::function_arg`: use `&Bound<'_, T>` instead for this function argument
--> tests/ui/deprecations.rs:116:29
--> tests/ui/deprecations.rs:114:29
|
116 | fn pyfunction_gil_ref(_any: &PyAny) {}
114 | fn pyfunction_gil_ref(_any: &PyAny) {}
| ^
error: use of deprecated method `pyo3::deprecations::OptionGilRefs::<std::option::Option<T>>::function_arg`: use `Option<&Bound<'_, T>>` instead for this function argument
--> tests/ui/deprecations.rs:119:36
--> tests/ui/deprecations.rs:117:36
|
119 | fn pyfunction_option_gil_ref(_any: Option<&PyAny>) {}
117 | fn pyfunction_option_gil_ref(_any: Option<&PyAny>) {}
| ^^^^^^
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor
--> tests/ui/deprecations.rs:126:27
--> tests/ui/deprecations.rs:124:27
|
126 | #[pyo3(from_py_with = "PyAny::len", item("my_object"))]
124 | #[pyo3(from_py_with = "PyAny::len", item("my_object"))]
| ^^^^^^^^^^^^
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor
--> tests/ui/deprecations.rs:136:27
--> tests/ui/deprecations.rs:134:27
|
136 | #[pyo3(from_py_with = "PyAny::len")] usize,
134 | #[pyo3(from_py_with = "PyAny::len")] usize,
| ^^^^^^^^^^^^
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor
--> tests/ui/deprecations.rs:142:31
--> tests/ui/deprecations.rs:140:31
|
142 | Zip(#[pyo3(from_py_with = "extract_gil_ref")] i32),
140 | Zip(#[pyo3(from_py_with = "extract_gil_ref")] i32),
| ^^^^^^^^^^^^^^^^^
error: use of deprecated method `pyo3::deprecations::GilRefs::<T>::from_py_with_arg`: use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor
--> tests/ui/deprecations.rs:149:27
--> tests/ui/deprecations.rs:147:27
|
149 | #[pyo3(from_py_with = "extract_gil_ref")]
147 | #[pyo3(from_py_with = "extract_gil_ref")]
| ^^^^^^^^^^^^^^^^^
error: use of deprecated method `pyo3::deprecations::GilRefs::<pyo3::Python<'_>>::is_python`: use `wrap_pyfunction_bound!` instead
--> tests/ui/deprecations.rs:162:13
--> tests/ui/deprecations.rs:160:13
|
162 | let _ = wrap_pyfunction!(double, py);
160 | let _ = wrap_pyfunction!(double, py);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `wrap_pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info)