On Fri, Nov 21, 2014 at 10:24 PM, Raymond Hettinger email@example.com wrote:
Please let me know if I'm reading the PEP correctly. Does the proposal break all existing code in generators that uses next() to raise StopIteration or that raises StopIteration explicitly?
For example, here is the pure python recipe for itertools.accumulate() show in the docs at https://docs.python.org/3/library/itertools.html#itertool-functions :
def accumulate(iterable, func=operator.add): 'Return running totals' # accumulate([1,2,3,4,5]) --> 1 3 6 10 15 # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120 it = iter(iterable) total = next(it) yield total for element in it: total = func(total, element) yield total
The case where the iterable is empty would now raise, yes.
Or would it break the traditional examples of how to write something like izip() using a generator?
def izip(iterable1, iterable2): it1 = iter(iterable1) it2 = iter(iterable2) while True: v1 = next(it1) v2 = next(it2) yield v1, v2 assert list(izip('ab', 'cde')) == [('a', 'c'), ('b', 'd')] assert list(izip('abc', 'cd')) == [('a', 'c'), ('b', 'd')]
Yes, this would be affected. This proposal causes a separation of generators and iterators, so it's no longer possible to pretend that they're the same thing.
Also, the PEP motivation seemed somewhat weak. Instead of listing known bugs or real-world development difficulties, it seems to hinge almost entirely some "being surprised" that list comprehensions and generator expressions aren't the same in every regard (they aren't).
The main point is one of exceptions being silently suppressed. Iterator protocol involves the StopIteration exception; generator protocol doesn't, yet currently a generator that raises StopIteration will quietly terminate. It's as if every generator is wrapped inside "try: ..... except StopIteration: pass". Would you accept any function being written with that kind of implicit suppression of any other exception?
P.S. On a more general note, I think that our biggest problem in the Python world is getting people to switch to Python 3. If we really want that to happen, we should develop a strong aversion to proposals that further increase the semantic difference between Python 2 and Python 3.
The recommended form of the code will work exactly the same way in both versions: explicitly catching StopIteration and using it as a signal that the function should terminate. The only difference is the behaviour of the non-recommended practice of allowing an exception to bubble part-way and then be implicitly caught.