[Python-ideas] yield-from and @coroutine decorator [was:x=(yield from) confusion]

Jacob Holm jh at improva.dk
Sat Apr 4 14:01:13 CEST 2009

Jacob Holm wrote:
> Here is one possible fix, never mind the syntax. We could change the 
> yield from expression from the current:
> RESULT = yield from EXPR
> by adding an extra form, possibly one of:
> RESULT = yield from EXPR with STARTEXPR
> RESULT = yield from EXPR as NAME starting with STARTEXPR(NAME)
> And letting STARTEXPR if given take the place of the initial _i.next() 
> in the expansion(s). The point is we need to yield *something* first, 
> before rerouting all send(), next() and throw() calls to the subiterator.

Another possible fix would be to have new syntax for specifying that the 
initial call to the coroutine should be using send or throw instead. 
This could be seen as a restriction on what could be used as 
STARTEXPR(NAME) in the earlier syntax idea.

Yet another fix that requires no extra syntax would be to store the 
latest value yielded by the generator in a property on the generator 
(raising AttributeError before the first yield). Then the initial:

_y = _i.next()

could be replaced with:

    _y = _i.gi_latest_yield  # or whatever its name would be.
except AttributeError:
    _y = _i.next()

The benefit of this version is that it requires no new syntax, it avoids 
the extra next() call for coroutines, and it opens some new ways of 
using generators. It also supports almost everything that would be 
possible with the syntax-based fix. (Everything if the property is 
actually writable, but I don't really see a use for that except perhaps 
for deleting it).

I can even remember that I have wanted such a property before, although 
I don't recall the exact use case.

One bad thing about it is that the initial yield made by the yield-from 
is then the value that the coroutine decorator was meant to discard 
(usually None). That might be a reason for allowing the property to be 
writable, or for a change in syntax after all. On the other hand, if 
this is a problem you can manually call the coroutine the way you want 
before using it in yield-from, which would then initialize the value 
exactly like with the second syntax idea.

Of the three ideas so far, I much prefer the one without extra syntax.

- Jacob

More information about the Python-ideas mailing list