I recently came across some surprising behaviour in Python generators:
class YieldOne:
def __iter__(self):
try:
yield 1
except:
print '*Excepted Successfully*'
# raise
for i in YieldOne():
raise Exception('test exception')
Which gives the output:
*Excepted Successfully*
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
Exception: test exception
I was (pleasantly) surprised that *Excepted Successfully*
got printed, as this was what I wanted, but also surprised that the Exception still got propagated up to the top level. I was expecting to have to use the (commented in this example) raise
keyword to get the observed behaviour.
Can anyone explain why this functionality works as it does, and why the except
in the generator doesn't swallow the exception?
Is this the only instance in Python where an except
doesn't swallow an exception?