[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