[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