<p>You make an excellent point. I'm inclined to agree with you. Cheers</p>
<div class="gmail_quote">On Apr 11, 2012 6:50 PM, "Jacob Holm" <<a href="mailto:jh@improva.dk">jh@improva.dk</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hello Matt<br>
<br>
On 04/11/2012 11:38 AM, Matt Joiner wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Why can't generator.close() return the value if a StopIteration is raised?<br>
<br>
The PEPs mentioned that it was proposed before, but I can't find any<br>
definitive reason, and it's terribly convenient if it does.<br>
<br>
</blockquote>
<br>
What should be returned when you call close on an already-exhausted generator?<br>
<br>
You can't return the value of the final StopIteration unless you arrange to have that value stored somewhere.  Storing the value was deemed undesireable by the powers that be.<br>
<br>
The alternative is to return None if the generator is already exhausted.  That would work, but severely reduces the usefulness of the change.<br>
<br>
If you don't care about the performance of yield-from, it is quite easy to write a class you can use to wrap your generator-iterators and get the desired result (see untested example below).<br>
<br>
<br>
- Jacob<br>
<br>
<br>
import functools<br>
<br>
class generator_result_wrapper(<u></u>object):<br>
    __slots__ = ('_it', '_result')<br>
<br>
    def __init__(self, it):<br>
        self._it = it<br>
<br>
    def __iter__(self):<br>
        return self<br>
<br>
    def next(self):<br>
        try:<br>
            return self._it.next()<br>
        except StopIteration as e:<br>
            self._result = e.result<br>
            raise<br>
<br>
    def send(self, value):<br>
        try:<br>
            return self._it.send(value)<br>
        except StopIteration as e:<br>
            self._result = e.result<br>
            raise<br>
<br>
    def throw(self, *args, **kwargs):<br>
        try:<br>
            return self._it.throw(*args, **kwargs)<br>
        except StopIteration as e:<br>
            self._result = e.result<br>
            raise<br>
<br>
    def close(self):<br>
        try:<br>
            return self._result<br>
        except AttributeError:<br>
            pass<br>
        try:<br>
            self._it.throw(GeneratorExit)<br>
        except StopIteration as e:<br>
            self._result = e.result<br>
            return self._result<br>
        except GeneratorExit:<br>
            pass<br>
<br>
def close_result(func):<br>
    @functools.wraps(func)<br>
    def factory(*args, **kwargs):<br>
        return generator_result_wrapper(func(<u></u>*args, **kwargs))<br>
    return factory<br>
<br>
</blockquote></div>