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

Chris Angelico rosuav at gmail.com
Tue Nov 25 16:31:43 CET 2014


On Wed, Nov 26, 2014 at 2:20 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> I wouldn't interpret it like that.
>
> Calling next() on an empty iterator raises StopIteration. That's not a
> bug indicating a failure, it's the protocol working as expected. Your
> response to that may be to catch the StopIteration and ignore it, or to
> allow it to bubble up for something else to deal with it. Either way,
> next() raising StopIteration is not a bug, it is normal behaviour.
>
> (Failure to deal with any such StopIteration may be a bug.)
>
> However, if next() raises RuntimeError, that's not part of the protocol
> for iterators, so it is almost certainly a bug to be fixed. (Probably
> coming from an explicit "raise StopIteration" inside a generator
> function.) Your fix for the bug may be to refuse to fix it and just
> catch the exception and ignore it, but that's kind of nasty and hackish
> and shouldn't be considered good code.
>
> Do you agree this is a reasonable way to look at it?

Yes. Specifically, your parenthesis in the middle is the important
bit. If you have a csv.DictReader, KeyError might be an important part
of your protocol (maybe you have an optional column in the CSV file),
but it should be caught before it crosses the boundary of "part of
your protocol". At some point, it needs to be converted into
ValueError, perhaps, or replaced with a default value, or some other
coping mechanism is used. Failure to deal with StopIteration when
calling next() is failure to cope with all of that function's
protocol, and that is most likely to be a bug. (There are times, and
some of them have been mentioned in these discussion threads, where
calling next() can never raise StopIteration, so there need be no
try/except - eg it=iter(string.split(" ")) - but that just means that
a StopIteration from that call is an error somewhere else. I'm
definitely happy for that kind of "shouldn't happen" to turn into a
RuntimeError rather than being left as an unexpectedly-short
generator.)

ChrisA


More information about the Python-Dev mailing list