[Python-ideas] x=(yield from) confusion [was:Yet another alternative name for yield-from]

Jacob Holm jh at improva.dk
Sat Apr 4 03:47:50 CEST 2009

Nick Coghlan wrote:
> Jacob Holm wrote:
>> Since you are no longer pushing an alternative syntax for return but
>> still want a different exception, I'll assume there is some other
>> beginner mistake you are worried about.  My guess is it is some mistake
>> at the places where the generator is used, but I am having a hard time
>> figuring out where the mistake could be in ignoring the returned value. 
>> Perhaps you (or someone who has more time) can provide an example where
>> this is a bad thing?
> I can't speak for Guido, but the two easy beginner mistakes I think are
> worth preventing:
> - using 'return' where you meant 'yield' (however, if even 'return
> finally' doesn't appeal to Guido as alternative syntax for "no, this is
> a coroutine, I really mean it" then I'm fine with that)
Good, this one I understand.

> - trying to iterate normally over a coroutine instead of calling it
> appropriately (raising GeneratorReturn instead of StopIteration means
> that existing iterative code will let the new exception escape rather
> than silently suppressing the return exception)

But this one I still don't get.  Let me try a couple of cases:

1)  We have a coroutine that expects you to call send and/or throw with 
specific values, and ends up returning a value.  A beginner may try to 
iterate over it, but will most likely get an exception on the first 
next() call because the input is not valid. Or he would get an infinite 
loop because None is not changing the state of the coroutine.  In any 
case, it is unlikely that he will get to see either StopIteration or the 
new exception, because the input is not what the coroutine expects. The 
new exception doesn't help here.

2) We have a generator that e.g. pulls values from a file, yielding the 
processed values as it goes along, and returning some form of summary at 
the end.   If I iterate over it with a for-loop, I get all the values 
asn usual ... followed by an exception.  Why do I have to get an 
exception there just because the generator has some information that its 
implementer thought I might want?   Ignoring the value in this case 
seems perfectly reasonable, so having to catch an exception is just 
noise here.

3) We have a coroutine that computes something expensive, occationally 
yielding to let other code run. It neither sends or receives values, 
just uses yield for cooperative multitasking.  When it is done it 
returns a value.  If you loop over this coroutine, you will get a bunch 
of Nones, followed by the new exception.  You could argue that the new 
exception helps you here.  One way of accessing the returned value would 
be to catch it and look at an attribute.  However, for this case I would 
prefer to just call close on the generator to get the value afterwards.  
A beginner might be helped by the unexpected exception, but I think even 
a beginner would find that something strange was going on when the only 
value he gets for the loop variable is None.  He might even look up the 
documentation for the coroutine he was calling and see how it was 
supposed to be used.

4) ... ?

Do you have other concrete use cases I haven't thought of where a the 
new exception would help?

- Jacob

More information about the Python-ideas mailing list