[Python-ideas] Map and filter should also convert StopIteration to RuntimeError

Chris Angelico rosuav at gmail.com
Sat Dec 13 20:51:23 CET 2014


On Sun, Dec 14, 2014 at 6:02 AM, Devin Jeanpierre
<jeanpierreda at gmail.com> wrote:
> Terry was suggesting fixing builtin iterators, not fixing all iterators or the
> iterator protocol. It *is* Python's responsibility to make sure the
> builtin iterators are not broken. It's fine and to be expected if user
> code raises StopIteration, but map and filter don't handle it
> correctly and therefore disobey the iterator protocol, which is a bug
> in map and filter -- not the callback.

I'm not sure that "fine and to be expected" is necessarily true. If
the function given to map() raises StopIteration, I'd say any of these
approaches is justifiable:
1) It's an error. Raise something other than StopIteration, so the
caller knows something bad happened. (A generator version of map()
will do this post-479.)
2) It's to be expected. Consider map() to have now terminated. (In
other words, catch it and return.)
3) It's a signal that this one element should not be returned.
Suppress it, yield nothing, and go get the next value from the input
iterator.

Personally, I'd rank them in this order of preference. Consistency
with generators is a plus (especially in terms of citing a pure-Python
equivalent), and the second and especially third options risk opening
up a misfeature - using StopIteration as a weird form of flow
control/signalling. But your description implies that option 2 is
inherently obvious, which I'm not entirely convinced of; unless this
is actually implemented as a generic "this iterator is now exhausted"
flag, and next() itself sets and checks this flag, thus automatically
enforcing that one StopIteration will result in an infinite stream of
StopIterations.

ChrisA


More information about the Python-ideas mailing list