-
Notifications
You must be signed in to change notification settings - Fork 806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarified documentation for implementing iteration. #882
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thank you!
But generally, we don't need to implement __next__
for containers.
To clarify the relationship between container and iterator, I propose the below example.
#[pyclass]
struct Iter {
inner: std::vec::IntoIter<usize>,
}
#[pyproto]
impl PyIterProtocol for Iter {
fn __next__(mut slf: PyRefMut<'p, Self>) -> PyResult<Option<usize>> {
Ok(slf.inner.next())
}
}
#[pyclass]
struct Container {
iter: Vec<usize>,
}
#[pyproto]
impl PyIterProtocol for Container {
fn __iter__(slf: PyRef<'p, Self>) -> PyResult<Py<Iter>> {
let iter = Iter {
inner: slf.iter.clone().into_iter(),
};
PyCell::new(slf.py(), iter).map(Into::into)
}
}
You can test this example by
let gil = Python::acquire_gil();
let py = gil.python();
let inst = pyo3::PyCell::new(
py,
Container {
iter: vec![1, 2, 3, 4],
},
)
.unwrap();
py_assert!(py, inst, "list(inst) == [1, 2, 3, 4]");
(please use #
to hide the test).
In addition, it would be helpful to refer to Python doc.
Ah, I hadn't thought to check for default implementations of the protocol functions!
The version provided by the trait just panics (it calls Regarding your suggestion for the iterator implementation: iterators always need to implement I may well be missing something important about the current implementation of |
No. It's a bit difficult to explain, but TypeError: 'Container' object is not an iterator So I don't want to recommend users to implement a stub for
Yeah, you're right. Please fix the example to do so. |
I bet! I looked through that code a bit, but it's a bit dense :) I'll make the change you suggest regarding |
@kngwyu The tests are failing because py_assert! doesn't seem to be defined. Is it supposed to be made available somehow in the doc testing environment, or do I need to import it somehow? |
@abingham |
LGTM, thank you! |
Thank you! I learned a lot. |
Added a note about implementing the distinction between iterables and iterators. I stumbled over this a bit when I was implementing some bindings, so I thought some clarification would help.