Closed
Description
Required prerequisites
- Make sure you've read the documentation. Your issue may be addressed there.
- Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- Consider asking first in the Gitter chat room or in a Discussion.
What version (or hash if on master) of pybind11 are you using?
master (c4a05f)
Problem description
The bug is that as currently implemented, the first call to iterator::operator++
is semantically a no-op, since it calls iterator::advance()
, but operator*
also automatically calls advance()
if it has never been advanced yet (that is, when iterator::value
is null). So the two following snippets are equivalent:
// Snippet 1
py::iterator it = my_iterable.begin();
return *it; // Returns the first item, as expected
// Snippet 2
py::iterator it = my_iterable.begin();
++it;
return *it; // BUG: also returns the first item
I have locally added unit tests that reproduce the problem (see below), and I'm working on a fix.
Reproducible example code
Adding the following to test_pytypes.cpp:
m.def("get_second_item_from_iterable", [](const py::iterable &iter) {
py::iterator it = iter.begin();
++it;
return *it;
});
and to test_pytypes.py:
def test_get_second_item_from_iterable():
lins = [1, 2]
i = m.get_second_item_from_iterable(lins)
assert i == 2
Fails with:
___ test_get_second_item_from_iterable ___
def test_get_second_item_from_iterable():
lins = [1, 2]
i = m.get_second_item_from_iterable(lins)
> assert i == 2
E assert 1 == 2
i = 1
lins = [1, 2]
Is this a regression? Put the last known working version here if it is.
Not a regression