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

guido.van.rossum python-checkins at python.org
Tue Feb 28 21:58:17 CET 2006


Author: guido.van.rossum
Date: Tue Feb 28 21:58:17 2006
New Revision: 42680

Modified:
   peps/trunk/pep-0343.txt
Log:
Change the PEP to add that __exit__() must re-raise the exception
passed in, if any.  This appears to be a deviation from how the PEP
was originally seen; but I think it's essential to be able to make a
simple promise about generators decorated with @contextmanager.

Added the transition plan and the __future__ statement.

Also some miscellaneous cleanup.



Modified: peps/trunk/pep-0343.txt
==============================================================================
--- peps/trunk/pep-0343.txt	(original)
+++ peps/trunk/pep-0343.txt	Tue Feb 28 21:58:17 2006
@@ -227,21 +227,22 @@
 
         ctx = (EXPR).__context__()
         exit = exc.__exit__  # Not calling it yet
-        res = ctx.__enter__()
+        value = ctx.__enter__()
         exc = (None, None, None)
         try:
             try:
-                VAR = res    # Only if "as VAR" is present
+                VAR = value  # Only if "as VAR" is present
                 BLOCK
             except:
-                exc = sys.exc_info()
-                raise
+                exc = None
+                exit(*sys.exc_info())
         finally:
-            exit(*exc)
+            if exc:
+                exit(*exc)
 
-    Here, the lowercase variables are internal variables and not
-    accessible to the user; they will most likely be implemented as
-    special registers or stack positions.
+    Here, the lowercase variables (ctx, exit, value, exc) are internal
+    variables and not accessible to the user; they will most likely be
+    implemented as special registers or stack positions.
 
     The details of the above translation are intended to prescribe the
     exact semantics.  If any of the relevant methods are not found as
@@ -264,20 +265,32 @@
     object each time its __context__ method is invoked.
 
     If the "as VAR" part of the syntax is omitted, the "VAR =" part of
-    the translation is omitted (but abc.__enter__() is still called).
+    the translation is omitted (but ctx.__enter__() is still called).
 
-    The calling convention for abc.__exit__() is as follows.  If the
+    The calling convention for ctx.__exit__() is as follows.  If the
     finally-suite was reached through normal completion of BLOCK or
     through a non-local goto (a break, continue or return statement in
-    BLOCK), abc.__exit__() is called with three None arguments.  If
+    BLOCK), ctx.__exit__() is called with three None arguments.  If
     the finally-suite was reached through an exception raised in
-    BLOCK, abc.__exit__() is called with three arguments representing
+    BLOCK, ctx.__exit__() is called with three arguments representing
     the exception type, value, and traceback.
 
-    The motivation for this API to __exit__(), as opposed to the
-    argument-less __exit__() from PEP 310, was given by the
-    transactional() use case, example 3 below.  The template in that
-    example must commit or roll back the transaction depending on
+    IMPORTANT: if ctx.__exit__() is passed exception information, it
+    *must* re-raise the exception, unless it wants the exception to be
+    ignored.  That is, if ctx.__exit__() returns normally, execution
+    continues at the next statement after the with-statement, even if
+    an exception happened inside the with-statement.  However, if the
+    with-statement was left via a non-local goto (break, continue or
+    return), this non-local return is resumed when ctx.__exit__()
+    returns normally.  The motivation for this detail is to make a
+    try/except block in a context manager created from a decorated
+    generator behave exactly as if the body of the generator were
+    expanded in-line at the place of the with-statement.
+
+    The motivation for passing the exception details to __exit__(), as
+    opposed to the argument-less __exit__() from PEP 310, was given by
+    the transactional() use case, example 3 below.  The template in
+    that example must commit or roll back the transaction depending on
     whether an exception occurred or not.  Rather than just having a
     boolean flag indicating whether an exception occurred, we pass the
     complete exception information, for the benefit of an
@@ -291,6 +304,20 @@
     non-local goto should be considered unexceptional for the purposes
     of a database transaction roll-back decision.
 
+Transition Plan
+
+    In Python 2.5, the new syntax will only be recognized if a future
+    statement is present:
+
+        from __future__ import with_statement
+
+    This will make both 'with' and 'as' keywords.  Without the future
+    statement, using 'with' or 'as' as an identifier will cause a
+    DeprecationWarning to be issued.
+
+    In Python 2.6, the new syntax will always be recognized; 'with'
+    and 'as' are always keywords.
+
 Generator Decorator
 
     With PEP 342 accepted, it is possible to write a decorator
@@ -394,6 +421,7 @@
         - threading.Lock
         - threading.RLock
         - threading.Condition
+        - threading.Semaphore and threading.BoundedSemaphore
 
 Standard Terminology
 
@@ -598,6 +626,7 @@
                 yield None
             except:
                 db.rollback()
+                raise
             else:
                 db.commit()
 


More information about the Python-checkins mailing list