[Python-ideas] Possible PEP 380 tweak

Greg Ewing greg.ewing at canterbury.ac.nz
Sat Oct 30 01:03:21 CEST 2010


Jacob Holm wrote:

> The main thing to note is that the expression form of yield-from is
> mostly intended to make it easier to have cofunctions that return a
> value, and that there is a problem with reusing StopIteration for that
> purpose.

No, I don't think that's where the problem is, if I understand
correctly which problem you're referring to. The fact that cofunctions
as currently defined in PEP 3152 can't raise StopIteration and have it
propagate to the caller is a problem with the use of StopIteration
to signal the end of a cofunction. Whether the StopIteration carries
a value or not is irrelevant.

 > And since there are no return values, there is no
> problem with how "close" should treat them.

There's no problem with that *now*, because close() is currently
not defined as returning a value. A problem only arises if we
try to overload close() to mean "no more data to send in, give me
your result" as well as "bail out now and clean up". And as I
pointed out, there are other ways of signalling end of data that
work fine with things as they are.

> 2)  In PEP 3152, define "return <value>" in a cofunction to raise a new
> IterationResult exception with the value.

That would have to apply to *all* forms of return, not just ones
with a value.

>   <var> = (yield from <expr>).value
> 
> have the benefit that the PEP 3152 expansion could reraise the
> actual StopIteration as in:
> 
>   e = yield from f.__cocall__(*args, **kwargs)
>   if isinstance(e, IterationResult):
>       <var> = e.value
>   else:
>       raise e

There's another way to approach this: define cofunctions so that
'return' in one of its forms is the only way to raise an actual
StopIteration, and any explicitly raised StopIteration gets wrapped
in something else, such as CoStopIteration. The expansion would
then be

    try:
       result = yield from f.__cocall__(*args, **kwargs)
    except CoStopIteration as e:
       raise e.value

where e.value is the original StopIteration instance.

This would have the advantage of not requiring any change to
yield-from as it stands.

-- 
Greg



More information about the Python-ideas mailing list