[Python-checkins] r43303 - peps/trunk/pep-0343.txt

phillip.eby python-checkins at python.org
Sat Mar 25 01:26:27 CET 2006


Author: phillip.eby
Date: Sat Mar 25 01:26:26 2006
New Revision: 43303

Modified:
   peps/trunk/pep-0343.txt
Log:
Document the difference between a normal return from __exit__() and an
exception return.  Fix a problem with @contextmanager not detecting
a broken generator that yields after a throw().  Make @contextmanager
not reraise exceptions, but return a false value in that case instead.


Modified: peps/trunk/pep-0343.txt
==============================================================================
--- peps/trunk/pep-0343.txt	(original)
+++ peps/trunk/pep-0343.txt	Sat Mar 25 01:26:26 2006
@@ -312,6 +312,24 @@
     non-local goto should be considered unexceptional for the purposes
     of a database transaction roll-back decision.
 
+    To facilitate chaining of contexts, __exit__() methods should
+    *not* reraise the error that is passed in, because it is always the
+    responsibility of the *caller* to do any reraising.
+
+    That way, if the caller needs to tell whether the __exit__() 
+    invocation *failed* (as opposed to successfully cleaning up before
+    propagating the original error), it can do so.
+
+    If __exit__() returns without an error, this can then be
+    interpreted as success of the __exit__() method itself (whether the
+    original error is to be propagated or suppressed).
+
+    However, if __exit__() propagates an exception to its caller, this
+    means that __exit__() *itself* has failed.  Thus, __exit__()
+    methods should avoid raising errors unless they have actually 
+    failed.  (And allowing the original error to proceed isn't a 
+    failure.)
+
 Transition Plan
 
     In Python 2.5, the new syntax will only be recognized if a future
@@ -357,9 +375,12 @@
                else:
                    try:
                        self.gen.throw(type, value, traceback)
-                       return True
+                       raise RuntimeError("generator didn't stop after throw()")
                    except StopIteration:
                        return True
+                   except:
+                       if sys.exc_info()[1] is not value:
+                           raise    # only reraise if it's a new exception
 
         def contextmanager(func):
            def helper(*args, **kwds):


More information about the Python-checkins mailing list