[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