3

I'm trying to extend a C++ library by implementing the python iteration protocol on a class. The problem is that trying to raise a StopIteration exception from the next() method makes the program SegFault. The method I've used for raising the exception from the C++ code (in python.i) is the one described here: http://www.swig.org/Doc1.3/Python.html#Python_nn44

Although that list doesn't have the StopIteration exception listed this is what I've tried:

PyErr_SetString(PyExc_StopIteration, NULL);
Oin
  • 6,951
  • 2
  • 31
  • 55

2 Answers2

5

So the right answer seems to be that the next() method must return a PyObject* and also use SetNone. So it would look like this:

PyObject* next(PyObject* self) {
  if (i < n) {
         \\ go on iterating
  } else {
         PyErr_SetNone(PyExc_StopIteration);
         return NULL;
  }
}

Thanks to aix for the link!

zneak
  • 134,922
  • 42
  • 253
  • 328
Oin
  • 6,951
  • 2
  • 31
  • 55
1

The segfault is almost certainly caused by the NULL pointer you've passing to PyErr_SetString. Try the following instead:

PyErr_SetString(PyExc_StopIteration, "end of collection");

edit I've just come across the following excellent post, which you may find useful: How to create a generator/iterator with the Python C API?

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Yes. That doesn't seem to be recognized by the python interpreter as a StopIteration exception. It doesn't quit the loop and it just goes on forever. I think this might not be the right mechanism for raising errors at all? The code just seems to send that message to stderr, but no python exception is raised... – Oin Sep 19 '11 at 15:26
  • @mapleoin: Take a look at http://stackoverflow.com/questions/1815812/how-to-create-a-generator-iterator-with-the-python-c-api/1816961#1816961 if you haven't already. – NPE Sep 19 '11 at 15:31