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:
parent
32f10bcf53
commit
0d09dd2a6a
23
pep-0343.txt
23
pep-0343.txt
|
@ -312,6 +312,24 @@ Specification: The 'with' Statement
|
||||||
non-local goto should be considered unexceptional for the purposes
|
non-local goto should be considered unexceptional for the purposes
|
||||||
of a database transaction roll-back decision.
|
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
|
Transition Plan
|
||||||
|
|
||||||
In Python 2.5, the new syntax will only be recognized if a future
|
In Python 2.5, the new syntax will only be recognized if a future
|
||||||
|
@ -357,9 +375,12 @@ Generator Decorator
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self.gen.throw(type, value, traceback)
|
self.gen.throw(type, value, traceback)
|
||||||
return True
|
raise RuntimeError("generator didn't stop after throw()")
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
return True
|
return True
|
||||||
|
except:
|
||||||
|
if sys.exc_info()[1] is not value:
|
||||||
|
raise # only reraise if it's a new exception
|
||||||
|
|
||||||
def contextmanager(func):
|
def contextmanager(func):
|
||||||
def helper(*args, **kwds):
|
def helper(*args, **kwds):
|
||||||
|
|
Loading…
Reference in New Issue