generators and exceptions

Tim Peters tim.one at comcast.net
Sat Mar 15 23:20:46 EST 2003


[Clark C. Evans]
> Hello, I'm playing with 2.2 generators, and it seems
> that they don't like exceptions...

They play with exceptions as defined in the "Specification: Generators and
Exception Propagation" section of the generator PEP:

    http://www.python.org/peps/pep-0255.html


>     from __future__ import generators
>     class MyExc(Exception): pass
>     def mygen(val):
>         while val > 0:
>            if val % 2: raise MyExc
>            yield val
>            val =- 1

Presumably this last line was meant to be

             val -= 1

instead?

>     iterator = iter(mygen(4))
>     while 1:
>        try:
>           val = iterator.next()
>           print val
>        except MyExc: pass
>        except StopIteration: break
>
>
> Anyway, this _only_ prints out 4, instead of 4, 2
> as I expected.

Read the PEP and your expectations will change <wink>.  The code exactly as
you gave should obviously produce only 4 (val is set to -1 and so the loop
exits).  With the suggested guess at what was intended, it should still
produce only 4, but due to raising an exception within the generator when
val is 3 (instead of falling off the end because val is -1).

> I expect 4, 2 beacuse an equivalent iterator would produce 4, 2.

Unclear what that means ("equivalent iterator") -- if you raise an exception
within *any* function, and don't catch it within that function, the
function's useful life ends.  Generator functions aren't an exception to
this, and neither are functions implementing any other kind of iterator.

> It seems that generators die on the first exception... is there a way
> around this?

No.

> I'm asking beacuse I'm using generators in a non-blocking database
> system, where I want to raise WouldBlock in my generator, but still be
> able to call the generator at a later time when it may not block...

Resuming a generator that has raised a (any) exception results in
StopIteration getting raised immediately, so, no, you can't do that
directly.






More information about the Python-list mailing list