introduce `PyIterator::from_bound_object`
This commit is contained in:
parent
6776b90e15
commit
783e98b1a8
|
@ -15,7 +15,7 @@ use crate::{
|
|||
exceptions::{PyAttributeError, PyRuntimeError, PyStopIteration},
|
||||
panic::PanicException,
|
||||
types::{PyIterator, PyString},
|
||||
IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python,
|
||||
IntoPy, Py, PyAny, PyErr, PyNativeType, PyObject, PyResult, Python,
|
||||
};
|
||||
|
||||
pub(crate) mod cancel;
|
||||
|
@ -107,7 +107,10 @@ impl Coroutine {
|
|||
if let Some(future) = self.waker.as_ref().unwrap().initialize_future(py)? {
|
||||
// `asyncio.Future` must be awaited; fortunately, it implements `__iter__ = __await__`
|
||||
// and will yield itself if its result has not been set in polling above
|
||||
if let Some(future) = PyIterator::from_object(future).unwrap().next() {
|
||||
if let Some(future) = PyIterator::from_bound_object(&future.as_borrowed())
|
||||
.unwrap()
|
||||
.next()
|
||||
{
|
||||
// future has not been leaked into Python for now, and Rust code can only call
|
||||
// `set_result(None)` in `Wake` implementation, so it's safe to unwrap
|
||||
return Ok(future.unwrap().into());
|
||||
|
|
|
@ -2018,7 +2018,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
|||
}
|
||||
|
||||
fn iter(&self) -> PyResult<Bound<'py, PyIterator>> {
|
||||
PyIterator::from_object2(self)
|
||||
PyIterator::from_bound_object(self)
|
||||
}
|
||||
|
||||
fn get_type(&self) -> &'py PyType {
|
||||
|
|
|
@ -209,7 +209,7 @@ mod impl_ {
|
|||
impl<'py> BoundFrozenSetIterator<'py> {
|
||||
pub(super) fn new(frozenset: Bound<'py, PyFrozenSet>) -> Self {
|
||||
Self {
|
||||
it: PyIterator::from_object2(&frozenset).unwrap(),
|
||||
it: PyIterator::from_bound_object(&frozenset).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,14 +31,23 @@ pyobject_native_type_named!(PyIterator);
|
|||
pyobject_native_type_extract!(PyIterator);
|
||||
|
||||
impl PyIterator {
|
||||
/// Constructs a `PyIterator` from a Python iterable object.
|
||||
///
|
||||
/// Equivalent to Python's built-in `iter` function.
|
||||
/// Deprecated form of `PyIterator::from_bound_object`.
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyIterator::from_object` will be replaced by `PyIterator::from_bound_object` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn from_object(obj: &PyAny) -> PyResult<&PyIterator> {
|
||||
Self::from_object2(&obj.as_borrowed()).map(Bound::into_gil_ref)
|
||||
Self::from_bound_object(&obj.as_borrowed()).map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
pub(crate) fn from_object2<'py>(obj: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyIterator>> {
|
||||
/// Builds an iterator for an iterable Python object; the equivalent of calling `iter(obj)` in Python.
|
||||
///
|
||||
/// Usually it is more convenient to write [`obj.iter()`][crate::types::any::PyAnyMethods::iter],
|
||||
/// which is a more concise way of calling this function.
|
||||
pub fn from_bound_object<'py>(obj: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyIterator>> {
|
||||
unsafe {
|
||||
ffi::PyObject_GetIter(obj.as_ptr())
|
||||
.assume_owned_or_err(obj.py())
|
||||
|
@ -135,6 +144,7 @@ impl<'v> crate::PyTryFrom<'v> for PyIterator {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))]
|
||||
mod tests {
|
||||
use super::PyIterator;
|
||||
use crate::exceptions::PyTypeError;
|
||||
|
|
|
@ -289,7 +289,7 @@ mod impl_ {
|
|||
impl<'py> BoundSetIterator<'py> {
|
||||
pub(super) fn new(set: Bound<'py, PySet>) -> Self {
|
||||
Self {
|
||||
it: PyIterator::from_object2(&set).unwrap(),
|
||||
it: PyIterator::from_bound_object(&set).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue