[Python-Dev] Please reconsider PEP 479.
Petr Viktorin
encukou at gmail.com
Wed Nov 26 12:44:08 CET 2014
On Wed, Nov 26, 2014 at 12:24 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On 26 November 2014 at 18:30, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
>> Guido van Rossum wrote:
>>>
>>> Hm, that sounds like you're either being contrarian or Chris and I have
>>> explained it even worse than I thought.
>>
>> I'm not trying to be contrary, I just think the PEP could
>> explain more clearly what you're trying to achieve. The
>> rationale is too vague and waffly at the moment.
>>
>>> Currently, there are cases where list(x for x in xs if P(x)) works while
>>> [x for x in xs if P(x)] fails (when P(x) raises StopIteration). With the
>>> PEP, both cases will raise some exception
>>
>> That's a better explanation, I think.
>
> The other key aspect is that it changes the answer to the question
> "How do I gracefully terminate a generator function?". The existing
> behaviour has an "or" in the answer: "return from the generator frame,
> OR raise StopIteration from the generator frame". That then leads to
> the follow on question: "When should I use one over the other?".
>
> The "from __future__ import generator_stop" answer drops the "or", so
> it's just: "return from the generator frame".
>
> Raising *any* exception inside the generator, including StopIteration,
> then counts as non-graceful termination, bringing generators into line
> with the PEP 343 philosophy that "hiding flow control in macros makes
> your code inscrutable", where here, the hidden flow control is relying
> on the fact that a called function raising StopIteration will
> currently always gracefully terminate generator execution.
>
> The key downside is that it means relatively idiomatic code like:
>
> def my_generator():
> ...
> yield next(it)
> ...
>
> Now needs to be written out explicitly as:
>
> def my_generator():
> ...
> try:
> yield next(it)
> except StopIteration
> return
> ...
It could also be written as:
def my_generator():
try:
...
yield next(it)
...
except StopIteration
return
i.e. put the try-block around the whole body, not just the individual
yield. This emulates what's happenning in current Python, and it would
be faster than individual try blocks.
More information about the Python-Dev
mailing list