<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Nov 27, 2014 at 3:04 AM, Nick Coghlan <span dir="ltr"><<a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 27 November 2014 at 11:15, Guido van Rossum <<a href="mailto:guido@python.org">guido@python.org</a>> wrote:<br>
> On Wed, Nov 26, 2014 at 2:53 PM, Nick Coghlan <<a href="mailto:ncoghlan@gmail.com">ncoghlan@gmail.com</a>> wrote:<br>
>><br>
>> On 27 Nov 2014 06:35, "Guido van Rossum" <<a href="mailto:guido@python.org">guido@python.org</a>> wrote:<br>
>><br>
>> [...]<br>
>><br>
>> > I think we can put a number to "much faster" now -- 150 nsec per<br>
>> > try/except.<br>
>> ><br>
>> > I have serious misgivings about that decorator though -- I'm not sure<br>
>> > how viable it is to pass a flag from the function object to the execution<br>
>> > (which takes the code object, which is immutable) and how other Python<br>
>> > implementations would do that. But I'm sure it can be done through sheer<br>
>> > willpower. I'd call it the @hettinger decorator in honor of the PEP's most<br>
>> > eloquent detractor. :-)<br>
>><br>
>> I agree with everything you wrote in your reply, so I'll just elaborate a<br>
>> bit on my proposed implementation for the decorator idea.<br>
><br>
> This remark is ambiguous -- how strongly do you feel that this decorator<br>
> should be provided? (If so, it should be in the PEP.)<br>
<br>
</span>I think it makes sense to standardise it, but something like<br>
"itertools.allow_implicit_stop" would probably be better than having<br>
it as a builtin. (The only reason I suggested a builtin initially is<br>
because putting it in itertools didn't occur to me until later)<br>
<br>
Including the decorator provides a straightforward way to immediately<br>
start writing forward compatible code that's explicit about the fact<br>
it relies on the current StopIteration handling, without being<br>
excessively noisy relative to the status quo:<br>
<br>
# In a module with a generator that relies on the current behaviour<br>
from itertools import allow_implicit_stop<br>
<br>
@allow_implicit_stop<br>
def my_generator():<br>
...<br>
yield next(itr)<br>
...<br>
<br>
In terms of code diffs to ensure forward compatibility, it's 1 import<br>
statement per affected module, and 1 decorator line per affected<br>
generator, rather than at least 3 lines (for try/except/return) plus<br>
indentation changes for each affected generator. That's a useful<br>
benefit when it comes to minimising the impact on version control code<br>
annotation, etc.<br>
<br>
If compatibility with older Python versions is needed, then you could<br>
put something like the following in a compatibility module:<br>
<br>
try:<br>
from itertools import allow_implicit_stop<br>
except ImportError:<br>
# Allowing implicit stops is the default in older versions<br>
def allow_implicit_stop(g):<br>
return g<br clear="all"></blockquote></div><br></div><div class="gmail_extra">I understand that @allow_import_stop represents a compromise, an attempt at calming the waves that PEP 479 has caused. But I still want to push back pretty hard on this idea.<br><br>- It means we're forever stuck with two possible semantics for StopIteration raised in generators.<br><br>- It complicates the implementation, because (presumably) a generator marked with @allow_stop_import should not cause a warning when a StopIteration bubbles out -- so we actually need another flag to silence the warning.<br><br>- I don't actually know whether other Python implementations have the ability to copy code objects to change flags.<br><br></div><div class="gmail_extra">- It actually introduces a new incompatibility, that has to be solved in every module that wants to use it (as you show above), whereas just putting try/except around unguarded next() calls is fully backwards compatible.<br><br></div><div class="gmail_extra">- Its existence encourage people to use the decorator in favor of fixing their code properly.<br><br></div><div class="gmail_extra">- The decorator is so subtle that it probably needs to be explained to everyone who encounters it (and wasn't involved in this PEP discussion). Because of this I would strongly advise against using it to "fix" the itertools examples in the docs; it's just too magical. (IIRC only 2 examples actually depend on this.)<br><br>Let me also present another (minor) argument for PEP 479. Sometimes you want to take a piece of code presented as a generator and turn it into something else. You can usually do this pretty easily by e.g. replacing every "yield" by a call to print() or list.append(). But if there are any bare next() calls in the code you have to beware of those. If the code was originally written without relying on bare next(), the transformation would have been easier.<br></div><div class="gmail_extra"><br>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)</div>
</div></div>