Python Forum
raise exception within generator - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: raise exception within generator (/thread-27058.html)



raise exception within generator - bermudj - May-24-2020

Hi,

I have a generator

def myRange(start, end):
    while start < end:
          yield start
          start += 1
    raise StopIteration

for n in myRange(2, 5):
    print(n)
I get a runtime error generator raised StopIteration. If I remove the raising of the StopIteration it works fine.

I thought that the for would catch the StopIteration exception. myRange is an iterator as well as being a generator and the for would catch the StopIteration exception. Can't generators raise exceptions?


RE: raise exception within generator - buran - May-24-2020

You don't need to raise that StopIteration.
def myRange(start, end):
    while start < end:
        yield start
        start += 1
 
for n in myRange(2, 5):
    print(n)

spam = myRange(2, 5)
while True:
    print(next(spam))
Output:
2 3 4 2 3 4 Traceback (most recent call last): File "***", line 11, in <module> print(next(spam)) StopIteration
as you can see, it will raise it when needed.
In your code it handles the StopIteration when generator is exhausted, but then you raise the exception that is not handled


RE: raise exception within generator - bermudj - Jun-06-2020

Thanks for the reply.

According to the link below one has to handle any StopIteration exceptions one generates within the
generator itself. If one does not and lets the exception bubble out from the generator then Python turns it into a RuntimeError.

https://www.python.org/dev/peps/pep-0479/


RE: raise exception within generator - buran - Jun-06-2020

your understanding is correct - this is about handling StopIteration inside generatorn. So the proposal is if inside your generator a StopIterations is about to buble out, it will be replaced with RuntimeError and this will cause error when you call next() on your generator.
This may happen if you have iterator some_iterator and you call unguarded next(some_iterator). when it is exhausted it will raise StopIteration error. So, you should not allow this to happen and you need to handle it inside your generator. This is exactly the opposite to raisng it your self. There is even an example that says wrong as comment after raise StopIteration inside generator.

Your code in first post is exactly example how the PEP will affect older code. Note that you get RuntimeError, not StopIteration. That is the new behavior in accordance with the PEP - StopIteration error inside generator is replaced with RuntimeError. Thus you need to handle it inside your generator. But in this case you don't have to raise it artificially in the first place.