[Python-checkins] peps: Update PEP 479 from author.

georg.brandl python-checkins at python.org
Mon Nov 17 10:26:15 CET 2014

changeset:   5597:75a785922e8c
user:        Georg Brandl <georg at python.org>
date:        Mon Nov 17 10:26:09 2014 +0100
  Update PEP 479 from author.

  pep-0479.txt |  62 +++++++++++++++++++++++++++++++++++----
  1 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/pep-0479.txt b/pep-0479.txt
--- a/pep-0479.txt
+++ b/pep-0479.txt
@@ -29,15 +29,27 @@
 ``StopIteration`` can be absorbed by the generator construct.
+Background information
+When a generator frame is (re)started as a result of a ``__next__()``
+(or ``send()`` or ``throw()``) call, one of three outcomes can occur:
+* A yield point is reached, and the yielded value is returned.
+* The frame is returned from; ``StopIteration`` is raised.
+* An exception is thrown, which bubbles out.
 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]_
+is replaced with ``RuntimeError``, 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]_
+This affects the third outcome listed above, without altering any
+other effects.
 Consequences to existing code
@@ -56,19 +68,38 @@
 As this can break code, it is proposed to utilize the ``__future__``
 mechanism to introduce this, finally making it standard in Python 3.6
-or 3.7.
+or 3.7.  Any generator function constructed in the presence of this
+directive will have a flag set on its code object, and generators with
+the flag set will behave according to this proposal.  Once the feature
+becomes standard, the flag may be dropped; code should not inspect
+generators for it.  (GvR: """And the flag should somehow be
+transferred to the stack frame when the function is executed, so the
+right action can be taken when an exception is about to bubble out of
+that frame.""")
 Alternate proposals
+Raising something other than RuntimeError
+Rather than the generic ``RuntimeError``, it might make sense to raise
+a new exception type ``UnexpectedStopIteration``.  This has the
+downside of implicitly encouraging that it be caught; the correct
+action is to catch the original ``StopIteration``, not the chained
 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.
+one is raised, the generator has properly completed.  This subproposal
+has been withdrawn in favour of better options, but is retained for
 Making return-triggered StopIterations obvious
@@ -80,6 +111,23 @@
 ``StopIteration`` which can then be detected.  If it is not that
 subclass, it is an escaping exception rather than a return statement.
+Of the three outcomes listed above:
+* A yielded value, obviously, would still be returned.
+* If the frame is returned from, ``GeneratorReturn`` is raised.
+* If an instance of ``GeneratorReturn`` would be raised, instead an
+  instance of ``StopIteration`` would be raised.
+In the third case, the ``StopIteration`` would have the ``value`` of
+the original ``GeneratorReturn``, and would reference the original
+exception in its ``__cause__``.  If uncaught, this would clearly show
+the chaining of exceptions.
+This does *not* affect the discrepancy between generator expressions
+and list comprehensions, but allows generator-aware code (such as the
+contextlib and asyncio modules) to reliably differentiate between the
+second and third outcomes listed above.

Repository URL: https://hg.python.org/peps

More information about the Python-checkins mailing list