feature gate APIs using `into_gil_ref` (Part 1) (#4160)
This commit is contained in:
parent
d803f7f8df
commit
635cb8075c
|
@ -186,11 +186,11 @@ mod tests {
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
let array: [f32; 4] = [0.0, -16.0, 16.0, 42.0];
|
let array: [f32; 4] = [0.0, -16.0, 16.0, 42.0];
|
||||||
let pyobject = array.to_object(py);
|
let pyobject = array.to_object(py);
|
||||||
let pylist: &PyList = pyobject.extract(py).unwrap();
|
let pylist = pyobject.downcast_bound::<PyList>(py).unwrap();
|
||||||
assert_eq!(pylist[0].extract::<f32>().unwrap(), 0.0);
|
assert_eq!(pylist.get_item(0).unwrap().extract::<f32>().unwrap(), 0.0);
|
||||||
assert_eq!(pylist[1].extract::<f32>().unwrap(), -16.0);
|
assert_eq!(pylist.get_item(1).unwrap().extract::<f32>().unwrap(), -16.0);
|
||||||
assert_eq!(pylist[2].extract::<f32>().unwrap(), 16.0);
|
assert_eq!(pylist.get_item(2).unwrap().extract::<f32>().unwrap(), 16.0);
|
||||||
assert_eq!(pylist[3].extract::<f32>().unwrap(), 42.0);
|
assert_eq!(pylist.get_item(3).unwrap().extract::<f32>().unwrap(), 42.0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,11 +213,11 @@ mod tests {
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
let array: [f32; 4] = [0.0, -16.0, 16.0, 42.0];
|
let array: [f32; 4] = [0.0, -16.0, 16.0, 42.0];
|
||||||
let pyobject = array.into_py(py);
|
let pyobject = array.into_py(py);
|
||||||
let pylist: &PyList = pyobject.extract(py).unwrap();
|
let pylist = pyobject.downcast_bound::<PyList>(py).unwrap();
|
||||||
assert_eq!(pylist[0].extract::<f32>().unwrap(), 0.0);
|
assert_eq!(pylist.get_item(0).unwrap().extract::<f32>().unwrap(), 0.0);
|
||||||
assert_eq!(pylist[1].extract::<f32>().unwrap(), -16.0);
|
assert_eq!(pylist.get_item(1).unwrap().extract::<f32>().unwrap(), -16.0);
|
||||||
assert_eq!(pylist[2].extract::<f32>().unwrap(), 16.0);
|
assert_eq!(pylist.get_item(2).unwrap().extract::<f32>().unwrap(), 16.0);
|
||||||
assert_eq!(pylist[3].extract::<f32>().unwrap(), 42.0);
|
assert_eq!(pylist.get_item(3).unwrap().extract::<f32>().unwrap(), 42.0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -667,6 +667,7 @@ impl<'py, T> Borrowed<'py, 'py, T>
|
||||||
where
|
where
|
||||||
T: HasPyGilRef,
|
T: HasPyGilRef,
|
||||||
{
|
{
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub(crate) fn into_gil_ref(self) -> &'py T::AsRefTarget {
|
pub(crate) fn into_gil_ref(self) -> &'py T::AsRefTarget {
|
||||||
// Safety: self is a borrow over `'py`.
|
// Safety: self is a borrow over `'py`.
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub(crate) fn get_ssize_index(index: usize) -> Py_ssize_t {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementations used for slice indexing PySequence, PyTuple, and PyList
|
/// Implementations used for slice indexing PySequence, PyTuple, and PyList
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
macro_rules! index_impls {
|
macro_rules! index_impls {
|
||||||
(
|
(
|
||||||
$ty:ty,
|
$ty:ty,
|
||||||
|
@ -154,6 +155,7 @@ macro_rules! index_impls {
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[cold]
|
#[cold]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub(crate) fn index_len_fail(index: usize, ty_name: &str, len: usize) -> ! {
|
pub(crate) fn index_len_fail(index: usize, ty_name: &str, len: usize) -> ! {
|
||||||
panic!(
|
panic!(
|
||||||
"index {} out of range for {} of length {}",
|
"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)]
|
#[inline(never)]
|
||||||
#[cold]
|
#[cold]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub(crate) fn slice_start_index_len_fail(index: usize, ty_name: &str, len: usize) -> ! {
|
pub(crate) fn slice_start_index_len_fail(index: usize, ty_name: &str, len: usize) -> ! {
|
||||||
panic!(
|
panic!(
|
||||||
"range start index {} out of range for {} of length {}",
|
"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)]
|
#[inline(never)]
|
||||||
#[cold]
|
#[cold]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub(crate) fn slice_end_index_len_fail(index: usize, ty_name: &str, len: usize) -> ! {
|
pub(crate) fn slice_end_index_len_fail(index: usize, ty_name: &str, len: usize) -> ! {
|
||||||
panic!(
|
panic!(
|
||||||
"range end index {} out of range for {} of length {}",
|
"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)]
|
#[inline(never)]
|
||||||
#[cold]
|
#[cold]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub(crate) fn slice_index_order_fail(index: usize, end: usize) -> ! {
|
pub(crate) fn slice_index_order_fail(index: usize, end: usize) -> ! {
|
||||||
panic!("slice index starts at {} but ends at {}", index, end);
|
panic!("slice index starts at {} but ends at {}", index, end);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,8 +120,8 @@ macro_rules! py_run_impl {
|
||||||
|
|
||||||
/// Wraps a Rust function annotated with [`#[pyfunction]`](macro@crate::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
|
/// This can be used with [`PyModule::add_function`](crate::types::PyModuleMethods::add_function) to
|
||||||
/// functions to a [`PyModule`](crate::types::PyModule) - see its documentation for more
|
/// add free functions to a [`PyModule`](crate::types::PyModule) - see its documentation for more
|
||||||
/// information.
|
/// information.
|
||||||
///
|
///
|
||||||
/// During the migration from the GIL Ref API to the Bound API, the return type of this macro will
|
/// 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).
|
/// 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
|
/// This can be used with [`PyModule::add_function`](crate::types::PyModuleMethods::add_function) to
|
||||||
/// functions to a [`PyModule`](crate::types::PyModule) - see its documentation for more information.
|
/// add free functions to a [`PyModule`](crate::types::PyModule) - see its documentation for more
|
||||||
|
/// information.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! wrap_pyfunction_bound {
|
macro_rules! wrap_pyfunction_bound {
|
||||||
($function:path) => {
|
($function:path) => {
|
||||||
|
@ -183,7 +184,7 @@ macro_rules! wrap_pyfunction_bound {
|
||||||
/// Python module.
|
/// Python module.
|
||||||
///
|
///
|
||||||
/// Use this together with [`#[pymodule]`](crate::pymodule) and
|
/// 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_export]
|
||||||
macro_rules! wrap_pymodule {
|
macro_rules! wrap_pymodule {
|
||||||
($module:path) => {
|
($module:path) => {
|
||||||
|
|
|
@ -114,15 +114,18 @@ mod inner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'py> CatchWarnings<'py> {
|
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 warnings = py.import_bound("warnings")?;
|
||||||
let kwargs = [("record", true)].into_py_dict_bound(py);
|
let kwargs = [("record", true)].into_py_dict_bound(py);
|
||||||
let catch_warnings = warnings
|
let catch_warnings = warnings
|
||||||
.getattr("catch_warnings")?
|
.getattr("catch_warnings")?
|
||||||
.call((), Some(&kwargs))?;
|
.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 };
|
let _guard = Self { catch_warnings };
|
||||||
f(list)
|
f(&list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +142,7 @@ mod inner {
|
||||||
macro_rules! assert_warnings {
|
macro_rules! assert_warnings {
|
||||||
($py:expr, $body:expr, [$(($category:ty, $message:literal)),+] $(,)? ) => {{
|
($py:expr, $body:expr, [$(($category:ty, $message:literal)),+] $(,)? ) => {{
|
||||||
$crate::tests::common::CatchWarnings::enter($py, |w| {
|
$crate::tests::common::CatchWarnings::enter($py, |w| {
|
||||||
|
use $crate::types::{PyListMethods, PyStringMethods};
|
||||||
$body;
|
$body;
|
||||||
let expected_warnings = [$((<$category as $crate::type_object::PyTypeInfo>::type_object_bound($py), $message)),+];
|
let expected_warnings = [$((<$category as $crate::type_object::PyTypeInfo>::type_object_bound($py), $message)),+];
|
||||||
assert_eq!(w.len(), expected_warnings.len());
|
assert_eq!(w.len(), expected_warnings.len());
|
||||||
|
|
|
@ -14,6 +14,7 @@ fn foo(_py: crate::Python<'_>, _m: &crate::types::PyModule) -> crate::PyResult<(
|
||||||
::std::result::Result::Ok(())
|
::std::result::Result::Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
#[crate::pymodule]
|
#[crate::pymodule]
|
||||||
#[pyo3(crate = "crate")]
|
#[pyo3(crate = "crate")]
|
||||||
|
|
|
@ -491,6 +491,7 @@ impl<'a> Borrowed<'a, '_, PyByteArray> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> TryFrom<&'py PyAny> for &'py PyByteArray {
|
impl<'py> TryFrom<&'py PyAny> for &'py PyByteArray {
|
||||||
type Error = crate::PyErr;
|
type Error = crate::PyErr;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ mod not_limited_impls {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::ops::{Add, Div, Mul, Neg, Sub};
|
use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl PyComplex {
|
impl PyComplex {
|
||||||
/// Returns `|self|`.
|
/// Returns `|self|`.
|
||||||
pub fn abs(&self) -> c_double {
|
pub fn abs(&self) -> c_double {
|
||||||
|
@ -94,6 +95,7 @@ mod not_limited_impls {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> $trait for &'py PyComplex {
|
impl<'py> $trait for &'py PyComplex {
|
||||||
type Output = &'py PyComplex;
|
type Output = &'py PyComplex;
|
||||||
fn $fn(self, other: &'py PyComplex) -> &'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!(Mul, mul, *, ffi::_Py_c_prod);
|
||||||
bin_ops!(Div, div, /, ffi::_Py_c_quot);
|
bin_ops!(Div, div, /, ffi::_Py_c_quot);
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> Neg for &'py PyComplex {
|
impl<'py> Neg for &'py PyComplex {
|
||||||
type Output = &'py PyComplex;
|
type Output = &'py PyComplex;
|
||||||
fn neg(self) -> &'py PyComplex {
|
fn neg(self) -> &'py PyComplex {
|
||||||
|
|
|
@ -6,7 +6,9 @@ use crate::instance::{Borrowed, Bound};
|
||||||
use crate::py_result_ext::PyResultExt;
|
use crate::py_result_ext::PyResultExt;
|
||||||
use crate::types::any::PyAnyMethods;
|
use crate::types::any::PyAnyMethods;
|
||||||
use crate::types::{PyAny, PyList};
|
use crate::types::{PyAny, PyList};
|
||||||
use crate::{ffi, PyNativeType, Python, ToPyObject};
|
#[cfg(feature = "gil-refs")]
|
||||||
|
use crate::PyNativeType;
|
||||||
|
use crate::{ffi, Python, ToPyObject};
|
||||||
|
|
||||||
/// Represents a Python `dict`.
|
/// Represents a Python `dict`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -56,34 +58,11 @@ pyobject_native_type_core!(
|
||||||
);
|
);
|
||||||
|
|
||||||
impl PyDict {
|
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.
|
/// Creates a new empty dictionary.
|
||||||
pub fn new_bound(py: Python<'_>) -> Bound<'_, PyDict> {
|
pub fn new_bound(py: Python<'_>) -> Bound<'_, PyDict> {
|
||||||
unsafe { ffi::PyDict_New().assume_owned(py).downcast_into_unchecked() }
|
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.
|
/// Creates a new dictionary from the sequence given.
|
||||||
///
|
///
|
||||||
/// The sequence must consist of `(PyObject, PyObject)`. This is
|
/// The sequence must consist of `(PyObject, PyObject)`. This is
|
||||||
|
@ -100,6 +79,30 @@ impl PyDict {
|
||||||
})?;
|
})?;
|
||||||
Ok(dict)
|
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.
|
/// 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.
|
/// PyO3 implementation of an iterator for a Python `dict` object.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub struct PyDictIterator<'py>(BoundDictIterator<'py>);
|
pub struct PyDictIterator<'py>(BoundDictIterator<'py>);
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> Iterator for PyDictIterator<'py> {
|
impl<'py> Iterator for PyDictIterator<'py> {
|
||||||
type Item = (&'py PyAny, &'py PyAny);
|
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> {
|
impl<'py> ExactSizeIterator for PyDictIterator<'py> {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.0.len()
|
self.0.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> IntoIterator for &'a PyDict {
|
impl<'a> IntoIterator for &'a PyDict {
|
||||||
type Item = (&'a PyAny, &'a PyAny);
|
type Item = (&'a PyAny, &'a PyAny);
|
||||||
type IntoIter = PyDictIterator<'a>;
|
type IntoIter = PyDictIterator<'a>;
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use crate::types::PyIterator;
|
use crate::types::PyIterator;
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
|
use crate::PyNativeType;
|
||||||
use crate::{
|
use crate::{
|
||||||
err::{self, PyErr, PyResult},
|
err::{self, PyErr, PyResult},
|
||||||
ffi,
|
ffi,
|
||||||
ffi_ptr_ext::FfiPtrExt,
|
ffi_ptr_ext::FfiPtrExt,
|
||||||
py_result_ext::PyResultExt,
|
py_result_ext::PyResultExt,
|
||||||
types::any::PyAnyMethods,
|
types::any::PyAnyMethods,
|
||||||
Bound, PyAny, PyNativeType, PyObject, Python, ToPyObject,
|
Bound, PyAny, PyObject, Python, ToPyObject,
|
||||||
};
|
};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
@ -74,20 +76,6 @@ pyobject_native_type_core!(
|
||||||
);
|
);
|
||||||
|
|
||||||
impl PyFrozenSet {
|
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.
|
/// Creates a new frozenset.
|
||||||
///
|
///
|
||||||
/// May panic when running out of memory.
|
/// May panic when running out of memory.
|
||||||
|
@ -99,16 +87,6 @@ impl PyFrozenSet {
|
||||||
new_from_iter(py, elements)
|
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
|
/// Creates a new empty frozen set
|
||||||
pub fn empty_bound(py: Python<'_>) -> PyResult<Bound<'_, PyFrozenSet>> {
|
pub fn empty_bound(py: Python<'_>) -> PyResult<Bound<'_, PyFrozenSet>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -117,6 +95,31 @@ impl PyFrozenSet {
|
||||||
.downcast_into_unchecked()
|
.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.
|
/// Return the number of items in the set.
|
||||||
/// This is equivalent to len(p) on a 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.
|
/// PyO3 implementation of an iterator for a Python `frozenset` object.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub struct PyFrozenSetIterator<'py>(BoundFrozenSetIterator<'py>);
|
pub struct PyFrozenSetIterator<'py>(BoundFrozenSetIterator<'py>);
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> Iterator for PyFrozenSetIterator<'py> {
|
impl<'py> Iterator for PyFrozenSetIterator<'py> {
|
||||||
type Item = &'py super::PyAny;
|
type Item = &'py super::PyAny;
|
||||||
|
|
||||||
|
@ -217,6 +222,7 @@ impl<'py> Iterator for PyFrozenSetIterator<'py> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl ExactSizeIterator for PyFrozenSetIterator<'_> {
|
impl ExactSizeIterator for PyFrozenSetIterator<'_> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
|
@ -224,6 +230,7 @@ impl ExactSizeIterator for PyFrozenSetIterator<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> IntoIterator for &'py PyFrozenSet {
|
impl<'py> IntoIterator for &'py PyFrozenSet {
|
||||||
type Item = &'py PyAny;
|
type Item = &'py PyAny;
|
||||||
type IntoIter = PyFrozenSetIterator<'py>;
|
type IntoIter = PyFrozenSetIterator<'py>;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||||
use crate::instance::Borrowed;
|
use crate::instance::Borrowed;
|
||||||
use crate::py_result_ext::PyResultExt;
|
use crate::py_result_ext::PyResultExt;
|
||||||
|
use crate::{ffi, AsPyPointer, Bound, PyAny, PyErr, PyResult, PyTypeCheck};
|
||||||
#[cfg(feature = "gil-refs")]
|
#[cfg(feature = "gil-refs")]
|
||||||
use crate::PyDowncastError;
|
use crate::{PyDowncastError, PyNativeType};
|
||||||
use crate::{ffi, AsPyPointer, Bound, PyAny, PyErr, PyNativeType, PyResult, PyTypeCheck};
|
|
||||||
|
|
||||||
/// A Python iterator object.
|
/// A Python iterator object.
|
||||||
///
|
///
|
||||||
|
@ -54,6 +54,7 @@ impl PyIterator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'p> Iterator for &'p PyIterator {
|
impl<'p> Iterator for &'p PyIterator {
|
||||||
type Item = PyResult<&'p PyAny>;
|
type Item = PyResult<&'p PyAny>;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@ use crate::ffi_ptr_ext::FfiPtrExt;
|
||||||
use crate::instance::Borrowed;
|
use crate::instance::Borrowed;
|
||||||
use crate::internal_tricks::get_ssize_index;
|
use crate::internal_tricks::get_ssize_index;
|
||||||
use crate::types::{PySequence, PyTuple};
|
use crate::types::{PySequence, PyTuple};
|
||||||
use crate::{Bound, PyAny, 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::any::PyAnyMethods;
|
||||||
use crate::types::sequence::PySequenceMethods;
|
use crate::types::sequence::PySequenceMethods;
|
||||||
|
@ -55,26 +57,10 @@ pub(crate) fn new_from_iter<'py>(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PyList {
|
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.
|
/// 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
|
/// 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
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -109,17 +95,6 @@ impl PyList {
|
||||||
new_from_iter(py, &mut iter)
|
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.
|
/// Constructs a new empty list.
|
||||||
pub fn empty_bound(py: Python<'_>) -> Bound<'_, PyList> {
|
pub fn empty_bound(py: Python<'_>) -> Bound<'_, PyList> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -128,6 +103,34 @@ impl PyList {
|
||||||
.downcast_into_unchecked()
|
.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.
|
/// Returns the length of the list.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
|
@ -273,6 +276,7 @@ impl PyList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
index_impls!(PyList, "list", PyList::len, PyList::get_slice);
|
index_impls!(PyList, "list", PyList::len, PyList::get_slice);
|
||||||
|
|
||||||
/// Implementation of functionality for [`PyList`].
|
/// Implementation of functionality for [`PyList`].
|
||||||
|
@ -586,8 +590,10 @@ impl<'py> PyListMethods<'py> for Bound<'py, PyList> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Used by `PyList::iter()`.
|
/// Used by `PyList::iter()`.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub struct PyListIterator<'a>(BoundListIterator<'a>);
|
pub struct PyListIterator<'a>(BoundListIterator<'a>);
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> Iterator for PyListIterator<'a> {
|
impl<'a> Iterator for PyListIterator<'a> {
|
||||||
type Item = &'a PyAny;
|
type Item = &'a PyAny;
|
||||||
|
|
||||||
|
@ -602,6 +608,7 @@ impl<'a> Iterator for PyListIterator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> DoubleEndedIterator for PyListIterator<'a> {
|
impl<'a> DoubleEndedIterator for PyListIterator<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next_back(&mut self) -> Option<Self::Item> {
|
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> {
|
impl<'a> ExactSizeIterator for PyListIterator<'a> {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.0.len()
|
self.0.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl FusedIterator for PyListIterator<'_> {}
|
impl FusedIterator for PyListIterator<'_> {}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> IntoIterator for &'a PyList {
|
impl<'a> IntoIterator for &'a PyList {
|
||||||
type Item = &'a PyAny;
|
type Item = &'a PyAny;
|
||||||
type IntoIter = PyListIterator<'a>;
|
type IntoIter = PyListIterator<'a>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::err::{PyDowncastError, PyResult};
|
use crate::err::PyResult;
|
||||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||||
use crate::instance::Bound;
|
use crate::instance::Bound;
|
||||||
use crate::py_result_ext::PyResultExt;
|
use crate::py_result_ext::PyResultExt;
|
||||||
|
@ -6,7 +6,9 @@ use crate::sync::GILOnceCell;
|
||||||
use crate::type_object::PyTypeInfo;
|
use crate::type_object::PyTypeInfo;
|
||||||
use crate::types::any::PyAnyMethods;
|
use crate::types::any::PyAnyMethods;
|
||||||
use crate::types::{PyAny, PyDict, PySequence, PyType};
|
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.
|
/// Represents a reference to a Python object supporting the mapping protocol.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -14,6 +16,18 @@ pub struct PyMapping(PyAny);
|
||||||
pyobject_native_type_named!(PyMapping);
|
pyobject_native_type_named!(PyMapping);
|
||||||
pyobject_native_type_extract!(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 {
|
impl PyMapping {
|
||||||
/// Returns the number of objects in the mapping.
|
/// Returns the number of objects in the mapping.
|
||||||
///
|
///
|
||||||
|
@ -92,15 +106,6 @@ impl PyMapping {
|
||||||
pub fn items(&self) -> PyResult<&PySequence> {
|
pub fn items(&self) -> PyResult<&PySequence> {
|
||||||
self.as_borrowed().items().map(Bound::into_gil_ref)
|
self.as_borrowed().items().map(Bound::into_gil_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a pyclass as a subclass of `collections.abc.Mapping` (from the Python standard
|
|
||||||
/// 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`].
|
/// Implementation of functionality for [`PyMapping`].
|
||||||
|
@ -255,6 +260,7 @@ impl PyTypeCheck for PyMapping {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
impl<'v> crate::PyTryFrom<'v> for PyMapping {
|
impl<'v> crate::PyTryFrom<'v> for PyMapping {
|
||||||
/// Downcasting to `PyMapping` requires the concrete class to be a subclass (or registered
|
/// Downcasting to `PyMapping` requires the concrete class to be a subclass (or registered
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use crate::err::PyResult;
|
use crate::err::PyResult;
|
||||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||||
use crate::py_result_ext::PyResultExt;
|
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`.
|
/// Represents a Python `memoryview`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -31,6 +33,7 @@ impl PyMemoryView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> TryFrom<&'py PyAny> for &'py PyMemoryView {
|
impl<'py> TryFrom<&'py PyAny> for &'py PyMemoryView {
|
||||||
type Error = crate::PyErr;
|
type Error = crate::PyErr;
|
||||||
|
|
||||||
|
|
|
@ -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.
|
/// 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`].
|
/// In these cases the iterators are implemented by forwarding to [`PyIterator`].
|
||||||
pub mod iter {
|
pub mod iter {
|
||||||
pub use super::dict::{BoundDictIterator, PyDictIterator};
|
pub use super::dict::BoundDictIterator;
|
||||||
pub use super::frozenset::{BoundFrozenSetIterator, PyFrozenSetIterator};
|
pub use super::frozenset::BoundFrozenSetIterator;
|
||||||
pub use super::list::{BoundListIterator, PyListIterator};
|
pub use super::list::BoundListIterator;
|
||||||
pub use super::set::{BoundSetIterator, PySetIterator};
|
pub use super::set::BoundSetIterator;
|
||||||
pub use super::tuple::{BorrowedTupleIterator, BoundTupleIterator, PyTupleIterator};
|
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.
|
/// Python objects that have a base type.
|
||||||
|
|
|
@ -6,11 +6,12 @@ use crate::pyclass::PyClass;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
any::PyAnyMethods, list::PyListMethods, PyAny, PyCFunction, PyDict, PyList, PyString,
|
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::ffi::CString;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use super::PyStringMethods;
|
#[cfg(feature = "gil-refs")]
|
||||||
|
use {super::PyStringMethods, crate::PyNativeType};
|
||||||
|
|
||||||
/// Represents a Python [`module`][1] object.
|
/// 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);
|
pyobject_native_type_core!(PyModule, pyobject_native_static_type_object!(ffi::PyModule_Type), #checkfunction=ffi::PyModule_Check);
|
||||||
|
|
||||||
impl PyModule {
|
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`.
|
/// Creates a new module object with the `__name__` attribute set to `name`.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # 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.
|
/// Imports the Python module with the specified name.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # 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`,
|
/// Creates and loads a module named `module_name`,
|
||||||
/// containing the Python code passed to `code`
|
/// containing the Python code passed to `code`
|
||||||
/// and pretending to live at `file_name`.
|
/// and pretending to live at `file_name`.
|
||||||
|
@ -195,6 +155,47 @@ impl PyModule {
|
||||||
.downcast_into()
|
.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.
|
/// Returns the module's `__dict__` attribute, which contains the module's symbol table.
|
||||||
pub fn dict(&self) -> &PyDict {
|
pub fn dict(&self) -> &PyDict {
|
||||||
|
@ -433,8 +434,9 @@ pub trait PyModuleMethods<'py>: crate::sealed::Sealed {
|
||||||
|
|
||||||
/// Adds an attribute to the module.
|
/// Adds an attribute to the module.
|
||||||
///
|
///
|
||||||
/// For adding classes, functions or modules, prefer to use [`PyModule::add_class`],
|
/// For adding classes, functions or modules, prefer to use [`PyModuleMethods::add_class`],
|
||||||
/// [`PyModule::add_function`] or [`PyModule::add_submodule`] instead, respectively.
|
/// [`PyModuleMethods::add_function`] or [`PyModuleMethods::add_submodule`] instead,
|
||||||
|
/// respectively.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # 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.
|
/// 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<()>
|
fn add_wrapped<T>(&self, wrapper: &impl Fn(Python<'py>) -> T) -> PyResult<()>
|
||||||
where
|
where
|
||||||
T: IntoPyCallbackOutput<PyObject>;
|
T: IntoPyCallbackOutput<PyObject>;
|
||||||
|
|
|
@ -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::exceptions::PyTypeError;
|
||||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||||
#[cfg(feature = "experimental-inspect")]
|
#[cfg(feature = "experimental-inspect")]
|
||||||
|
@ -9,7 +9,9 @@ use crate::py_result_ext::PyResultExt;
|
||||||
use crate::sync::GILOnceCell;
|
use crate::sync::GILOnceCell;
|
||||||
use crate::type_object::PyTypeInfo;
|
use crate::type_object::PyTypeInfo;
|
||||||
use crate::types::{any::PyAnyMethods, PyAny, PyList, PyString, PyTuple, PyType};
|
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.
|
/// Represents a reference to a Python object supporting the sequence protocol.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -17,6 +19,18 @@ pub struct PySequence(PyAny);
|
||||||
pyobject_native_type_named!(PySequence);
|
pyobject_native_type_named!(PySequence);
|
||||||
pyobject_native_type_extract!(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 {
|
impl PySequence {
|
||||||
/// Returns the number of objects in sequence.
|
/// Returns the number of objects in sequence.
|
||||||
///
|
///
|
||||||
|
@ -175,15 +189,6 @@ impl PySequence {
|
||||||
pub fn to_tuple(&self) -> PyResult<&PyTuple> {
|
pub fn to_tuple(&self) -> PyResult<&PyTuple> {
|
||||||
self.as_borrowed().to_tuple().map(Bound::into_gil_ref)
|
self.as_borrowed().to_tuple().map(Bound::into_gil_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a pyclass as a subclass of `collections.abc.Sequence` (from the Python standard
|
|
||||||
/// 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`].
|
/// Implementation of functionality for [`PySequence`].
|
||||||
|
@ -465,16 +470,19 @@ impl<'py> PySequenceMethods<'py> for Bound<'py, PySequence> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
fn sequence_len(seq: &PySequence) -> usize {
|
fn sequence_len(seq: &PySequence) -> usize {
|
||||||
seq.len().expect("failed to get sequence length")
|
seq.len().expect("failed to get sequence length")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
fn sequence_slice(seq: &PySequence, start: usize, end: usize) -> &PySequence {
|
fn sequence_slice(seq: &PySequence, start: usize, end: usize) -> &PySequence {
|
||||||
seq.get_slice(start, end)
|
seq.get_slice(start, end)
|
||||||
.expect("sequence slice operation failed")
|
.expect("sequence slice operation failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
index_impls!(PySequence, "sequence", sequence_len, sequence_slice);
|
index_impls!(PySequence, "sequence", sequence_len, sequence_slice);
|
||||||
|
|
||||||
impl<'py, T> FromPyObject<'py> for Vec<T>
|
impl<'py, T> FromPyObject<'py> for Vec<T>
|
||||||
|
@ -539,6 +547,7 @@ impl PyTypeCheck for PySequence {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
impl<'v> crate::PyTryFrom<'v> for PySequence {
|
impl<'v> crate::PyTryFrom<'v> for PySequence {
|
||||||
/// Downcasting to `PySequence` requires the concrete class to be a subclass (or registered
|
/// Downcasting to `PySequence` requires the concrete class to be a subclass (or registered
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
use crate::types::PyIterator;
|
use crate::types::PyIterator;
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
|
use crate::PyNativeType;
|
||||||
use crate::{
|
use crate::{
|
||||||
err::{self, PyErr, PyResult},
|
err::{self, PyErr, PyResult},
|
||||||
ffi_ptr_ext::FfiPtrExt,
|
ffi_ptr_ext::FfiPtrExt,
|
||||||
instance::Bound,
|
instance::Bound,
|
||||||
py_result_ext::PyResultExt,
|
py_result_ext::PyResultExt,
|
||||||
types::any::PyAnyMethods,
|
types::any::PyAnyMethods,
|
||||||
PyNativeType,
|
|
||||||
};
|
};
|
||||||
use crate::{ffi, PyAny, PyObject, Python, ToPyObject};
|
use crate::{ffi, PyAny, PyObject, Python, ToPyObject};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -29,9 +30,31 @@ pyobject_native_type_core!(
|
||||||
#checkfunction=ffi::PySet_Check
|
#checkfunction=ffi::PySet_Check
|
||||||
);
|
);
|
||||||
|
|
||||||
|
impl PySet {
|
||||||
|
/// 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 {
|
impl PySet {
|
||||||
/// Deprecated form of [`PySet::new_bound`].
|
/// Deprecated form of [`PySet::new_bound`].
|
||||||
#[cfg(feature = "gil-refs")]
|
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
since = "0.21.0",
|
since = "0.21.0",
|
||||||
note = "`PySet::new` will be replaced by `PySet::new_bound` in a future PyO3 version"
|
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)
|
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`].
|
/// Deprecated form of [`PySet::empty_bound`].
|
||||||
#[cfg(feature = "gil-refs")]
|
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
since = "0.21.2",
|
since = "0.21.2",
|
||||||
note = "`PySet::empty` will be replaced by `PySet::empty_bound` in a future PyO3 version"
|
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)
|
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.
|
/// Removes all elements from the set.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn clear(&self) {
|
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.
|
/// PyO3 implementation of an iterator for a Python `set` object.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub struct PySetIterator<'py>(BoundSetIterator<'py>);
|
pub struct PySetIterator<'py>(BoundSetIterator<'py>);
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> Iterator for PySetIterator<'py> {
|
impl<'py> Iterator for PySetIterator<'py> {
|
||||||
type Item = &'py super::PyAny;
|
type Item = &'py super::PyAny;
|
||||||
|
|
||||||
|
@ -279,12 +283,14 @@ impl<'py> Iterator for PySetIterator<'py> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl ExactSizeIterator for PySetIterator<'_> {
|
impl ExactSizeIterator for PySetIterator<'_> {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.0.len()
|
self.0.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> IntoIterator for &'py PySet {
|
impl<'py> IntoIterator for &'py PySet {
|
||||||
type Item = &'py PyAny;
|
type Item = &'py PyAny;
|
||||||
type IntoIter = PySetIterator<'py>;
|
type IntoIter = PySetIterator<'py>;
|
||||||
|
|
|
@ -7,9 +7,11 @@ use crate::inspect::types::TypeInfo;
|
||||||
use crate::instance::Borrowed;
|
use crate::instance::Borrowed;
|
||||||
use crate::internal_tricks::get_ssize_index;
|
use crate::internal_tricks::get_ssize_index;
|
||||||
use crate::types::{any::PyAnyMethods, sequence::PySequenceMethods, PyList, PySequence};
|
use crate::types::{any::PyAnyMethods, sequence::PySequenceMethods, PyList, PySequence};
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
|
use crate::PyNativeType;
|
||||||
use crate::{
|
use crate::{
|
||||||
exceptions, Bound, FromPyObject, IntoPy, Py, PyAny, PyErr, PyNativeType, PyObject, PyResult,
|
exceptions, Bound, FromPyObject, IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python,
|
||||||
Python, ToPyObject,
|
ToPyObject,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[inline]
|
#[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);
|
pyobject_native_type_core!(PyTuple, pyobject_native_static_type_object!(ffi::PyTuple_Type), #checkfunction=ffi::PyTuple_Check);
|
||||||
|
|
||||||
impl PyTuple {
|
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.
|
/// 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
|
/// 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)
|
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).
|
/// Constructs an empty tuple (on the Python side, a singleton object).
|
||||||
pub fn empty_bound(py: Python<'_>) -> Bound<'_, PyTuple> {
|
pub fn empty_bound(py: Python<'_>) -> Bound<'_, PyTuple> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -132,6 +106,35 @@ impl PyTuple {
|
||||||
.downcast_into_unchecked()
|
.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.
|
/// Gets the length of the tuple.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
|
@ -236,6 +239,7 @@ impl PyTuple {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
index_impls!(PyTuple, "tuple", PyTuple::len, PyTuple::get_slice);
|
index_impls!(PyTuple, "tuple", PyTuple::len, PyTuple::get_slice);
|
||||||
|
|
||||||
/// Implementation of functionality for [`PyTuple`].
|
/// Implementation of functionality for [`PyTuple`].
|
||||||
|
@ -443,8 +447,10 @@ impl<'a, 'py> Borrowed<'a, 'py, PyTuple> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Used by `PyTuple::iter()`.
|
/// Used by `PyTuple::iter()`.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub struct PyTupleIterator<'a>(BorrowedTupleIterator<'a, 'a>);
|
pub struct PyTupleIterator<'a>(BorrowedTupleIterator<'a, 'a>);
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> Iterator for PyTupleIterator<'a> {
|
impl<'a> Iterator for PyTupleIterator<'a> {
|
||||||
type Item = &'a PyAny;
|
type Item = &'a PyAny;
|
||||||
|
|
||||||
|
@ -459,6 +465,7 @@ impl<'a> Iterator for PyTupleIterator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> DoubleEndedIterator for PyTupleIterator<'a> {
|
impl<'a> DoubleEndedIterator for PyTupleIterator<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next_back(&mut self) -> Option<Self::Item> {
|
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> {
|
impl<'a> ExactSizeIterator for PyTupleIterator<'a> {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.0.len()
|
self.0.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl FusedIterator for PyTupleIterator<'_> {}
|
impl FusedIterator for PyTupleIterator<'_> {}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> IntoIterator for &'a PyTuple {
|
impl<'a> IntoIterator for &'a PyTuple {
|
||||||
type Item = &'a PyAny;
|
type Item = &'a PyAny;
|
||||||
type IntoIter = PyTupleIterator<'a>;
|
type IntoIter = PyTupleIterator<'a>;
|
||||||
|
|
|
@ -10,6 +10,7 @@ fn basic_function(py: pyo3::Python<'_>, x: Option<pyo3::PyObject>) -> pyo3::PyOb
|
||||||
x.unwrap_or_else(|| py.None())
|
x.unwrap_or_else(|| py.None())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
#[pyo3::pymodule]
|
#[pyo3::pymodule]
|
||||||
fn basic_module(_py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> {
|
fn basic_module(_py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> {
|
||||||
|
@ -108,7 +109,7 @@ impl BasicClass {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic() {
|
fn test_basic() {
|
||||||
pyo3::Python::with_gil(|py| {
|
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 cls = py.get_type_bound::<BasicClass>();
|
||||||
let d = pyo3::types::IntoPyDict::into_py_dict_bound(
|
let d = pyo3::types::IntoPyDict::into_py_dict_bound(
|
||||||
[
|
[
|
||||||
|
|
|
@ -58,8 +58,8 @@ fn pyfunction_with_module<'py>(module: &Bound<'py, PyModule>) -> PyResult<Bound<
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
#[pyo3(pass_module)]
|
#[pyo3(pass_module)]
|
||||||
fn pyfunction_with_module_gil_ref(module: &PyModule) -> PyResult<&str> {
|
fn pyfunction_with_module_gil_ref(_module: &PyModule) -> PyResult<&str> {
|
||||||
module.name()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
|
@ -68,14 +68,12 @@ fn double(x: usize) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymodule]
|
#[pymodule]
|
||||||
fn module_gil_ref(m: &PyModule) -> PyResult<()> {
|
fn module_gil_ref(_m: &PyModule) -> PyResult<()> {
|
||||||
m.add_function(wrap_pyfunction!(double, m)?)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymodule]
|
#[pymodule]
|
||||||
fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
fn module_gil_ref_with_explicit_py_arg(_py: Python<'_>, _m: &PyModule) -> PyResult<()> {
|
||||||
m.add_function(wrap_pyfunction!(double, m)?)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
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
|
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
|
--> 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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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)
|
= note: this error originates in the macro `wrap_pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
Loading…
Reference in New Issue