[Python-ideas] x=(yield from) confusion [was:Yet another alternative name for yield-from]
Jacob Holm
jh at improva.dk
Sun Apr 5 18:40:50 CEST 2009
Greg Ewing wrote:
> Guido van Rossum wrote:
>> I don't believe that once the generator has raised StopIteration or
>> ReturnFromGenerator, the return value should be saved somewhere to be
>> retrieved with an explicit close() call -- I want to be able to free
>> all resources once the generator frame is dead.
>
> I agree with that.
I don't think it is common to keep the generator object alive long after
the generator is closed, so I don't see the problem in keeping the value
so it can be returned by the next close() call.
>
> As a corollary, I *don't* think that close() should
> return the value of a ReturnFromGenerator even if it
> gets one, because unless the value is stored, you'll
> only get it the first time close() is called, and
> only if the generator has not already completed
> normally. That would make it too unreliable for any
> practical use as far as I can see.
>
And I think it is a mistake to have close() swallow the return value. If
it catches ReturnFromGenerator, it should also return the value or raise
a RuntimeError.
In my order of preference:
1. "return value" in a generator raises StopIteration(value). Any
exception raised by next, send or throw sets a return value on the
generator on the way out. If the exception is a StopIteration or
GeneratorExit (see below) that was not the argument to throw, the
value is taken from there, else it is None. Any next(), send(), or
throw() operation on a closed generator raises a new StopIteration
using the saved value. When close catches a StopIteration or
GeneratorExit it returns the value. After yield-from calls close
as part of its GeneratorExit handling, it raises a new
GeneratorExit with the returned value.
The GeneratorExit part lets "def outer(): return yield from
inner()" behave as expected.
2. Same as #1 but using ReturnFromGenerator(value) instead of
StopIteration.
3. Same as #1 but without attaching return value to GeneratorExit in
yield-from.
4. Same as #3 but using ReturnFromGenerator(value) instead of
StopIteration.
5. Same as #1 but without storing the value on the generator.
6. Same as #5 but using ReturnFromGenerator(value) instead of
StopIteration.
7. "return value" in a generator raises ReturnFromGenerator(value).
close() doesn't catch it.
8. "return value" in a generator raises ReturnFromGenerator(value).
close() catches ReturnFromGenerator and raises a RuntimeError.
9. Anything else that has been suggested. In particular anything
where close() catches ReturnFromGenerator without either returning
the value or raising another exception.
Too many options? This is just a small subset of what has been discussed.
- Jacob
More information about the Python-ideas
mailing list