3

I've found example of how to implement PyIterProtocol in Rust.

use pyo3::prelude::*;
use pyo3::PyIterProtocol;
use pyo3::class::iter::IterNextOutput;

#[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")
        }
    }
}

but I cannot figure out how to implement a container class that is iterable but is not a iterator itself. Essentially I want to be able to decompose my object in Python like

x, y, z = my_object
alagris
  • 1,838
  • 16
  • 31

1 Answers1

2

From the user guide on Iterator Types:

In many cases you'll have a distinction between the type being iterated over (i.e. the iterable) and the iterator it provides. In this case, you should implement PyIterProtocol for both the iterable and the iterator, but the iterable only needs to support __iter__() while the iterator must support both __iter__() and __next__().

Masklinn
  • 34,759
  • 3
  • 38
  • 57