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.
This commit is contained in:
Phillip J. Eby 2006-03-25 00:26:26 +00:00
parent 32f10bcf53
commit 0d09dd2a6a
1 changed files with 22 additions and 1 deletions

View File

@ -312,6 +312,24 @@ Specification: The 'with' Statement
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 @@ Generator Decorator
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):