Re: [Python-Dev] Another PEP 343 contextmanager glitch

At 03:05 PM 3/24/2006 -0800, Guido van Rossum wrote:
Oops, that's definitely a bug. Please go ahead and fix in both places.
Will do.
(I'm still trying to fathom the other PEP 343 issue you brought up.)
Here's the paragraph I'm proposing to add to the PEP to explain that issue:
NOTE: 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 reraise. If an __exit__() method exits with *any* exception, the caller of __exit__() should interpret this as meaning that the __exit__() method itself failed to perform the desired cleanup or other operations.
Currently, the PEP is ambiguous on this point. When "with" calls __exit__() this point is irrelevant because either way, the same exception will be raised/propagated.
But if you are writing Python code that explicitly uses the context protocol (e.g. the 'nested' context manager), it should be clear as to whether a given __exit__() invocation failed or succeeded. Thus, __exit__() should only raise an exception if it *failed*.
(This then implies that the @contextmanager decorator must catch any re-raising done by the wrapped generator.)

On 3/24/06, Phillip J. Eby pje@telecommunity.com wrote:
At 03:05 PM 3/24/2006 -0800, Guido van Rossum wrote:
Oops, that's definitely a bug. Please go ahead and fix in both places.
Will do.
(I'm still trying to fathom the other PEP 343 issue you brought up.)
Here's the paragraph I'm proposing to add to the PEP to explain that issue:
NOTE: 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 reraise. If an __exit__() method exits with *any* exception, the caller of __exit__() should interpret this as meaning that the __exit__() method itself failed to perform the desired cleanup or other operations.
Currently, the PEP is ambiguous on this point. When "with" calls __exit__() this point is irrelevant because either way, the same exception will be raised/propagated.
But if you are writing Python code that explicitly uses the context protocol (e.g. the 'nested' context manager), it should be clear as to whether a given __exit__() invocation failed or succeeded. Thus, __exit__() should only raise an exception if it *failed*.
(This then implies that the @contextmanager decorator must catch any re-raising done by the wrapped generator.)
I guess I like the ambiguity -- to the outer __exit__, it shouldn't make any difference whether the exception was re-raised by the inner __exit__ or by the finally clause containing it. After all, if there *wasn't* an outer __exit__, there wouldn't be any difference to the user either, whether the re-raise came from __exit__ or from finally.
If you still disagree, can you produce a test case that's currently broken?
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (2)
-
Guido van Rossum
-
Phillip J. Eby