Re: [Python-ideas] PEP 479: Change StopIteration handling inside generators

I htink I'm getting closer to clarity here, but:
let's say I have this silly helper function (similar to the one in the PEP):
## (sorry -- python2)
def helper(x): if x > 2: raise StopIteration else: return x
# I call that helper from both an iterator class and a generator function.
class Iter(object): def __init__(self): self.x = 0 def __iter__(self): return self def next(self): if self.x == 3: raise StopIteration self.x += 1 return helper(self.x)
def gen(): yield helper(1) yield helper(2) yield helper(3)
# first just loop through them:
for i in Iter(): print i
for i in gen(): print i
# they act exactly the same
# then put them inside generator expression and loop through that:
for j in ( i for i in gen() ): print j
for j in ( i for i in Iter() ): print j
# they still act exactly the same.
Would this PEP chance that? would that StopIteration bubble up through the iterator class, but not through the generator function? If so then I'm -1 on the PEP.
The only change made by this proposal is that StopIteration becomes,
in a generator, like any other unexpected exception.
but from the user's perspective, an iterator and a generator should look the same.
And I think from the perspective of the author of a given generator function, they should look as much the same as possible-- i.e. if a StopIteration is raised internally, it will behave the same way as it would in a iterator class.
It creates a
separation between "iterator protocol" (which is implemented by __next__) and "generator protocol" (which is written in the body of a function with 'yield' in it).
terminology messing me up here -- I understood the "iterator protocol" top mean the __iter__ and __next__ -- and a generator satisfies that protocol. Is there a "generator protocol" that means somethign different?
Maybe that's what this whole sub-thread is about:
I never thought there was such a thing as a "generator protocol", and I don't see why there should be.
-Chris

On Sat, Nov 22, 2014 at 6:33 AM, Chris Barker chris.barker@noaa.gov wrote:
And I think from the perspective of the author of a given generator function, they should look as much the same as possible-- i.e. if a StopIteration is raised internally, it will behave the same way as it would in a iterator class.
Ah, but why? When you write a function like this:
def gen(): yield 1 yield 2
why should StopIteration mean any more to it than, say, KeyError does?
It creates a separation between "iterator protocol" (which is implemented by __next__) and "generator protocol" (which is written in the body of a function with 'yield' in it).
terminology messing me up here -- I understood the "iterator protocol" top mean the __iter__ and __next__ -- and a generator satisfies that protocol. Is there a "generator protocol" that means somethign different?
A generator *object* does. A generator *function* doesn't - it follows a protocol that consists of the "yield" and "return" statements.
ChrisA
participants (2)
-
Chris Angelico
-
Chris Barker