[python] can I stop iteration without exception being thrown?

Hi, I an using vector_indexing_suite for both standard containers export and for our in-house ones. I've noticed that boost::python::error_already_set is bwing thrown every time iteration in python over container instances is about to finish. The exception is ignored somewhere inside boost::python but it's still quite inconvenient for debugging: I want to catch actual error, but can't skip 100s of fake ones. Is there any reason why it was designed this way? Is there any way to avoid it? Gennadiy

Gennadiy Rozental wrote:
Hi,
I an using vector_indexing_suite for both standard containers export and for our in-house ones. I've noticed that boost::python::error_already_set is bwing thrown every time iteration in python over container instances is about to finish. The exception is ignored somewhere inside boost::python but it's still quite inconvenient for debugging: I want to catch actual error, but can't skip 100s of fake ones. Is there any reason why it was designed this way? Is there any way to avoid it?
I believe you can use python::stl_input_iterator (boost/python/stl_iterator.hpp) to iterate over a python sequence, and it won't throw an exception. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler <eric <at> boost-consulting.com> writes:
Gennadiy Rozental wrote:
Hi,
I an using vector_indexing_suite for both standard containers export and for I believe you can use python::stl_input_iterator (boost/python/stl_iterator.hpp) to iterate over a python sequence, and it won't throw an exception.
No. I need iteration in python over exported c++ collection not to cause exception to be generated in C++: mymodule.cpp class_<std::vector<Foo>, boost::noncopyable >( "FooArray" ) .... .def( vector_indexing_suite<std::vector<Foo> >() ) ; test.py: def test_foo(): arr = mymodule.FooArray( 5 ) for e in arr: pass This code causes an exception being thrown to stop iteration. I just wonder if there is means to avoid it. Gennadiy

Gennadiy Rozental wrote:
This code causes an exception being thrown to stop iteration. I just wonder if there is means to avoid it.
Out of curiosity, what's the problem with code throwing an exception, as long as it is properly caught ? User's shouldn't even have to be aware of that. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Stefan Seefeld <seefeld <at> sympatico.ca> writes:
Gennadiy Rozental wrote:
This code causes an exception being thrown to stop iteration. I just wonder if there is means to avoid it.
Out of curiosity, what's the problem with code throwing an exception, as long as it is properly caught ?
In general? Setting aside potential performance consequences, exceptions have to be used only to report error conditions, not as end of loop indicator.
User's shouldn't even have to be aware of that.
Users like me unfortunately become very aware of it. Gennadiy

Gennadiy Rozental wrote:
This code causes an exception being thrown to stop iteration. I just wonder if there is means to avoid it.
Out of curiosity, what's the problem with code throwing an exception, as long as it is properly caught ?
In general? Setting aside potential performance consequences, exceptions have to be used only to report error conditions, not as end of loop indicator.
Beside the fact that I completely agree with you (but probably because I'm a C++ developer), you have to be aware that Python and C++ philosophies differ dramatically. On this precise point, while C++ developers are attached to a well-defined balance between return codes and exceptions, Python has pushed the use of exceptions to an extreme. This often leads to things that are considered as worst practices and/or beginner mistakes in other languages, like the fact of stopping an iteration by throwing. In Python, the assertion that "exceptions should only handle errors" is unfortunately false. Bruno

Bruno Lalande wrote:
Gennadiy Rozental wrote:
This code causes an exception being thrown to stop iteration. I just wonder if there is means to avoid it.
Out of curiosity, what's the problem with code throwing an exception, as long as it is properly caught ?
In general? Setting aside potential performance consequences, exceptions have to be used only to report error conditions, not as end of loop indicator.
Beside the fact that I completely agree with you (but probably because I'm a C++ developer), you have to be aware that Python and C++ philosophies differ dramatically. On this precise point, while C++ developers are attached to a well-defined balance between return codes and exceptions, Python has pushed the use of exceptions to an extreme. This often leads to things that are considered as worst practices and/or beginner mistakes in other languages, like the fact of stopping an iteration by throwing. In Python, the assertion that "exceptions should only handle errors" is unfortunately false.
And even in C++... Wasn't there some discussion on this list a little while ago about using exceptions to interrupt tree or graph traversals, being conceptually and technically easier than to check after each node for various conditions ? FWIW, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Stefan Seefeld <seefeld <at> sympatico.ca> writes:
And even in C++... Wasn't there some discussion on this list a little while ago about using exceptions to interrupt tree or graph traversals, being conceptually and technically easier than to check after each node for various conditions ?
Throwing exception is easy way out in many situations. It doesn't make it right though. I guess there are always exceptions that prove the rule (especially if performance is not a concern). But if there is a way to avoid it I'd opt to it. Gennadiy

Bruno Lalande <bruno.lalande <at> gmail.com> writes:
Beside the fact that I completely agree with you (but probably because I'm a C++ developer), you have to be aware that Python and C++ philosophies differ dramatically. On this precise point, while C++ developers are attached to a well-defined balance between return codes and exceptions, Python has pushed the use of exceptions to an extreme. This often leads to things that are considered as worst practices and/or beginner mistakes in other languages, like the fact of stopping an iteration by throwing. In Python, the assertion that "exceptions should only handle errors" is unfortunately false.
I guess it's ok. To the point where Boost.Python starts to throw C++ exceptions. Why does library chosen to follow python practice and not C++ is unclear to me. Gennadiy

Gennadiy Rozental wrote:
Hi,
I an using vector_indexing_suite for both standard containers export and for our in-house ones. I've noticed that boost::python::error_already_set is bwing thrown every time iteration in python over container instances is about to finish. The exception is ignored somewhere inside boost::python but it's still quite inconvenient for debugging: I want to catch actual error, but can't skip 100s of fake ones. Is there any reason why it was designed this way? Is there any way to avoid it?
A 'StopIteration' exception is the mechanism by which Python terminates an iteration. This exception is certainly not ignored. It is simply translated and handed over to the Python runtime. I'm not sure I understand how that gets into the way of debugging. However, you don't need to use iterators to traverse a container. Simply fetching a container's size and then use the usual operator[] works fine, too (though it might well be slower). Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Stefan Seefeld <seefeld <at> sympatico.ca> writes:
Gennadiy Rozental wrote: A 'StopIteration' exception is the mechanism by which Python terminates an iteration. This exception is certainly not ignored. It is simply translated and handed over to the Python runtime. I'm not sure I
Kinda against the rules for good programming
understand how that gets into the way of debugging.
VS has nice feature I like to use th at allows to catch exceptions in the point of inception. If I enable it these StopIteration exceptions start to creep up and make debugging impossible.
However, you don't need to use iterators to traverse a container. Simply fetching a container's size and then use the usual operator[] works fine, too (though it might well be slower).
python code is written using regular for construct Gennadiy

Gennadiy Rozental wrote:
Stefan Seefeld <seefeld <at> sympatico.ca> writes:
Gennadiy Rozental wrote: A 'StopIteration' exception is the mechanism by which Python terminates an iteration. This exception is certainly not ignored. It is simply translated and handed over to the Python runtime. I'm not sure I
Kinda against the rules for good programming
Only true for languages where exceptions are used to indicate errors. Some languages allow you to recover from exceptions and retry the operation (but Python is not one of them, afaik!) -- Sohail Somani http://uint32t.blogspot.com

Gennadiy Rozental wrote:
python code is written using regular for construct Yes, and that works like this:
http://docs.python.org/tut/node11.html#SECTION0011900000000000000000 HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Gennadiy Rozental wrote:
VS has nice feature I like to use th at allows to catch exceptions in the point of inception. If I enable it these StopIteration exceptions start to creep up and make debugging impossible.
VS (7.0+) also has the feature that you can register (add) exception types and have VS ignore them when they are thrown. We do this for the few exceptions we use in a similar manner in our app. This should perhaps go into the documentation of libs that make liberal use of exceptions, as a courtesy to users who find it annoying. mvh /Marcus

Marcus Lindblom <macke <at> yar.nu> writes:
Gennadiy Rozental wrote:
VS has nice feature I like to use th at allows to catch exceptions in the point of inception. If I enable it these StopIteration exceptions start to creep up and make debugging impossible.
VS (7.0+) also has the feature that you can register (add) exception types and have VS ignore them when they are thrown. We do this for the few exceptions we use in a similar manner in our app.
This should perhaps go into the documentation of libs that make liberal use of exceptions, as a courtesy to users who find it annoying.
Unfortunately Boost.Python is using single exception class for all error conditions and this is an exception I am interested catching. Gennadiy
participants (6)
-
Bruno Lalande
-
Eric Niebler
-
Gennadiy Rozental
-
Marcus Lindblom
-
Sohail Somani
-
Stefan Seefeld