PEP: 479
Title: Change StopIteration handling inside generators
Version: $Revision$
Last-Modified: $Date$
Author: Chris Angelico <rosuav@gmail.com>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 15-Nov-2014
Python-Version: 3.5
Post-History: 15-Nov-2014
Abstract
========
This PEP proposes a semantic change to ``StopIteration`` when raised
inside a generator, unifying the behaviour of list comprehensions and
generator expressions somewhat.
Rationale
=========
The interaction of generators and ``StopIteration`` is currently
somewhat surprising, and can conceal obscure bugs. An unexpected
exception should not result in subtly altered behaviour, but should
cause a noisy and easily-debugged traceback. Currently,
``StopIteration`` can be absorbed by the generator construct.
Proposal
========
If a ``StopIteration`` is about to bubble out of a generator frame, it
is replaced with some other exception (maybe ``RuntimeError``, maybe a
new custom ``Exception`` subclass, but *not* deriving from
``StopIteration``) which causes the ``next()`` call (which invoked the
generator) to fail, passing that exception out. From then on it's
just like any old exception. [3]_
Alternate proposals
===================
Supplying a specific exception to raise on return
-------------------------------------------------
Nick Coghlan suggested a means of providing a specific
``StopIteration`` instance to the generator; if any other instance of
``StopIteration`` is raised, it is an error, but if that particular
one is raised, the generator has properly completed.
Making return-triggered StopIterations obvious
----------------------------------------------
For certain situations, a simpler and fully backward-compatible
solution may be sufficient: when a generator returns, instead of
raising ``StopIteration``, it raises a specific subclass of
``StopIteration`` which can then be detected. If it is not that
subclass, it is an escaping exception rather than a return statement.