[Python-ideas] PEP 479: Change StopIteration handling inside generators
Wolfgang Maier
wolfgang.maier at biologie.uni-freiburg.de
Thu Nov 20 23:58:51 CET 2014
On 20.11.2014 03:06, Steven D'Aprano wrote:
> On Thu, Nov 20, 2014 at 03:24:07AM +1100, Chris Angelico wrote:
>
>> Without the generator, *only* __next__ has
>> this effect, and that's exactly where it's documented to be.
>
> The documentation states that __next__ raises StopIteration, it doesn't
> say that *only* __next__ should raise StopIteration.
>
> https://docs.python.org/3/library/stdtypes.html#iterator.__next__
>
> I trust that we all expect to be able to factor out the raise into a
> helper function or method, yes? It truly would be surprising if this
> failed:
>
>
> class MyIterator:
> def __iter__(self):
> return self
> def __next__(self):
> return something()
>
>
> def something():
> # Toy helper function.
> if random.random() < 0.5:
> return "Spam!"
> raise StopIteration
>
>
>
> Now let's write this as a generator:
>
> def gen():
> while True:
> yield something()
>
>
> which is much nicer than:
>
> def gen():
> while True:
> try:
> yield something()
> except StopIteration:
> return # converted by Python into raise StopIteration
>
I find this example a compelling argument against the PEP. Personally,
I'm dealing a lot more often with refactoring a generator function into
a iterator class than I'm rewriting generator expressions into
comprehensions (at least the exotic kinds that would reveal their
inequality).
So for me at least, the burden of having to remember that I can let (and
should let) StopIteration bubble up inside __next__, but not in
generator functions weighs in heavier than the equality argument and the
protection against hard-to-diagnose (but rarely occurring) bugs in
nested generator functions.
More information about the Python-ideas
mailing list