From 412beeb4e372768b103c1634a6edc311eb2c791b Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 25 Nov 2014 18:17:13 -0800 Subject: [PATCH] No empty promises in the abstract. Extend rationale. --- pep-0479.txt | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/pep-0479.txt b/pep-0479.txt index 3c67a3a6a..4fde5a2f7 100644 --- a/pep-0479.txt +++ b/pep-0479.txt @@ -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 ======================