No empty promises in the abstract. Extend rationale.

This commit is contained in:
Guido van Rossum 2014-11-25 18:17:13 -08:00
parent 906fec97d7
commit 412beeb4e3
1 changed files with 29 additions and 7 deletions

View File

@ -14,13 +14,10 @@ Post-History: 15-Nov-2014, 19-Nov-2014
Abstract
========
This PEP proposes a semantic change to ``StopIteration`` when raised
inside a generator. This would unify the behaviour of list
comprehensions and generator expressions, reducing surprises such as
the one that started this discussion [1]_. This is also the main
backwards incompatibility of the proposal -- any generator that
depends on raising ``StopIteration`` to terminate it will
have to be rewritten to either catch that exception or use a for-loop.
This PEP proposes a backwards incompatible change to generators: when
``StopIteration`` is raised inside a generator, it is replaced it with
``RuntimeError``. (More precisely, this happens when the exception is
about to bubble out of the generator's stack frame.)
Rationale
@ -32,6 +29,31 @@ 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.
The main goal of the proposal is to ease debugging in the situation
where an unguarded ``next()`` call (perhaps several stack frames deep)
raises ``StopIteration`` and causes the iteration controlled by the
generator to terminate silently. (When another exception is raised, a
traceback is printed pinpointing the cause of the problem.)
The proposal also clears up the confusion about how to terminate a
generator: the proper way is ``return``, not ``raise StopIteration``.
Finally, the proposal reduces the difference between list
comprehensions and generator expressions, preventing surprises such as
the one that started this discussion [1]_. Henceforth, the following
statements will produce the same result if either produces a result at
all::
a = list(F(x) for x in xs if P(x))
a = [F(x) for x in xs if P(x)]
With the current state of affairs, it is possible to write a function
``F(x)`` or a predicate ``P(x)`` that causes the first form to produce
a (truncated) result, while the second form raises an exception
(namely, ``StopIteration``). With the proposed change, both forms
will raise an exception at this point (albeit ``RuntimeError`` in the
first case and ``StopIteration`` in the second).
Background information
======================