[Python-ideas] Revised revised revised PEP on yield-from

Greg Ewing greg.ewing at canterbury.ac.nz
Mon Feb 16 22:52:42 CET 2009


Guido van Rossum wrote:

> (a) I don't know if the PEP proposes that "yield from expr" should
> return the last value returned by (i.e. sent to) a yield somewhere
> deeply nested; I think this would be useful.

No, it doesn't. Its value is the value passed to the
'return' statement that terminates the subgenerator
(and generators are enhanced to permit return with a
value).

My reason for doing this is so you can use subgenerators
like functions in a generator that's being used as
a lightweight thread.

> (b) I hope the PEP also explains what to do if "expr" is not a
> generator but some other kind of iterator.

Yes, it does. Currently I'm proposing that, if the
relevant methods are not defined, send() is treated
like next(), and throw() and close() do what they
would have done normally on the parent generator.

> (c) A quick skim of the PEP didn't show suggestions for how to
> implement this.

One way would be to simply emit the bytecode corresponding
to the presented expansion, although that wouldn't be
very efficient in terms of either speed or code size.

The PEP also sketches an optimised implementation in
which the generator has a slot which refers to the
generator being delegated to. Calls to next(), send(),
throw() and close() are forwarded via this slot if it
is nonempty.

There will still be a small overhead involved in the
delegation, but it's only a chain of C function calls
instead of Python ones, which ought to be a big
improvement.

It might be possible to reduce the overhead even further
by following the chain of delegation pointers in a loop
until reaching the end and then calling the end
generator directly. It would be trickier to get right,
though, because you'd have to be prepared to back up
and try earlier generators in the face of StopIterations.

-- 
Greg




More information about the Python-ideas mailing list