1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#![allow(deprecated)]
// Copyright (c) 2017-present PyO3 Project and Contributors
//! Python Iterator Interface.
//! Trait and support implementation for implementing iterators
use crate::callback::IntoPyCallbackOutput;
use crate::derive_utils::TryFromPyCell;
use crate::{PyClass, PyObject};
/// Python Iterator Interface.
///
/// Check [CPython doc](https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_iter)
/// for more.
///
/// # Examples
/// The following example shows how to implement a simple Python iterator in Rust which yields
/// the integers 1 to 5, before raising `StopIteration("Ended")`.
///
/// ```rust
/// # #![allow(deprecated, elided_lifetimes_in_paths)]
/// use pyo3::class::iter::IterNextOutput;
/// use pyo3::prelude::*;
/// use pyo3::PyIterProtocol;
///
/// #[pyclass]
/// struct Iter {
/// count: usize,
/// }
///
/// #[pyproto]
/// impl PyIterProtocol for Iter {
/// fn __next__(mut slf: PyRefMut<Self>) -> IterNextOutput<usize, &'static str> {
/// if slf.count < 5 {
/// slf.count += 1;
/// IterNextOutput::Yield(slf.count)
/// } else {
/// IterNextOutput::Return("Ended")
/// }
/// }
/// }
///
/// # Python::with_gil(|py| {
/// # let inst = Py::new(py, Iter { count: 0 }).unwrap();
/// # pyo3::py_run!(py, inst, "assert next(inst) == 1");
/// # }); // test of StopIteration is done in pytests/src/pyclasses.rs
/// ```
#[allow(unused_variables)]
#[deprecated(since = "0.16.0", note = "prefer `#[pymethods]` to `#[pyproto]`")]
pub trait PyIterProtocol<'p>: PyClass {
fn __iter__(slf: Self::Receiver) -> Self::Result
where
Self: PyIterIterProtocol<'p>,
{
unimplemented!()
}
fn __next__(slf: Self::Receiver) -> Self::Result
where
Self: PyIterNextProtocol<'p>,
{
unimplemented!()
}
}
pub trait PyIterIterProtocol<'p>: PyIterProtocol<'p> {
type Receiver: TryFromPyCell<'p, Self>;
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyIterNextProtocol<'p>: PyIterProtocol<'p> {
type Receiver: TryFromPyCell<'p, Self>;
type Result: IntoPyCallbackOutput<PyIterNextOutput>;
}
py_unarys_func!(iter, PyIterIterProtocol, Self::__iter__);
py_unarys_func!(iternext, PyIterNextProtocol, Self::__next__);
pub use crate::pyclass::{IterNextOutput, PyIterNextOutput};