Skip to content

Attempting to iterate over python iterable, in c++, iterates past the end with bound c++ types. #896

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

Closed
ariaTim opened this issue Jun 9, 2017 · 1 comment

Comments

@ariaTim
Copy link

ariaTim commented Jun 9, 2017

Issue

Attempting to iterate over python iterable, in c++, iterates past the end with bound c++ types. It seems that comparing the end iterator to the sentinel attempts to advance the end iterator past the end. When iterating a python type calling PyIter_Next past the end simply returns NULL however for a bound STL container this invokes undefined behaviour.

Occurs on:
Windows 10 (VS 2017), Ubuntu 17.04 (gcc 7.0)
pybind11 2.1.1 and master ( 0365d49 )

Example

cpp:

#include <pybind11/pybind11.h>
#include <pybind11/stl_bind.h>

namespace py = pybind11;

PYBIND11_MAKE_OPAQUE(std::vector<int>)

PYBIND11_MODULE(IterableTest, m)
{
    py::bind_vector<std::vector<int>>(m, "VectorInt");

    m.def("iter_test", [] (py::iterable iterable)
    {
        auto iter = py::iter(iterable);
        while (iter != py::iterator::sentinel())
        {
            py::print("got value: ", *iter);
            ++iter;
        }
    });
}

python:

from IterableTest import *

ivec = VectorInt()
ivec.append(3)
ivec.append(2)
ivec.append(1)

iter_test(ivec)

example output:

got value:  3
got value:  2
got value:  1
*debug assert iterator is not incrementable*
dean0x7d added a commit to dean0x7d/pybind11 that referenced this issue Jun 9, 2017
Fixes pybind#896.

From Python docs: Once an iterator’s `__next__()` method raises
`StopIteration`, it must continue to do so on subsequent calls.
Implementations that do not obey this property are deemed broken.
@dean0x7d
Copy link
Member

dean0x7d commented Jun 9, 2017

Thanks for reporting the bug! Should be fixed in #897.

dean0x7d added a commit to dean0x7d/pybind11 that referenced this issue Jun 10, 2017
Fixes pybind#896.

From Python docs: "Once an iterator’s `__next__()` method raises
`StopIteration`, it must continue to do so on subsequent calls.
Implementations that do not obey this property are deemed broken."
dean0x7d added a commit that referenced this issue Jun 10, 2017
Fixes #896.

From Python docs: "Once an iterator’s `__next__()` method raises
`StopIteration`, it must continue to do so on subsequent calls.
Implementations that do not obey this property are deemed broken."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants