Skip to content

Commit

Permalink
introduce PyIterator::from_bound_object
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Dec 29, 2023
1 parent 6776b90 commit d034f61
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 10 deletions.
7 changes: 5 additions & 2 deletions src/coroutine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion src/types/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/types/frozenset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}
}
}
Expand Down
19 changes: 14 additions & 5 deletions src/types/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,22 @@ 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>> {
/// Constructs a `PyIterator` from a Python iterable object.
///
/// Equivalent to Python's built-in `iter` 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())
Expand Down Expand Up @@ -135,6 +143,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;
Expand Down
2 changes: 1 addition & 1 deletion src/types/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}
}
}
Expand Down

0 comments on commit d034f61

Please sign in to comment.