[Python-Dev] with-statement heads-up
Guido van Rossum
guido at python.org
Tue Feb 28 19:07:36 CET 2006
On 2/28/06, Mike Bland <mbland at acm.org> wrote:
> On 2/28/06, Guido van Rossum <guido at python.org> wrote:
> > I just realized that there's a bug in the with-statement as currently
> > checked in. __exit__ is supposed to re-raise the exception if there
> > was one; if it returns normally, the finally clause is NOT to re-raise
> > it. The fix is relatively simple (I believe) but requires updating
> > lots of unit tests. It'll be a while.
>
> Hmm. My understanding was that __exit__ was *not* to reraise it, but
> was simply given the opportunity to record the exception-in-progress.
Yes, that's what the PEP said. :-(
Unfortunately the way the PEP is specified, the intended equivalence
between writing a try/except in a @contextmanager-decorated generator
and writing things out explicitly is lost. The plan was that this:
@contextmanager
def foo():
try:
yield
except Exception:
pass
with foo():
1/0
would be equivalent to this:
try:
1/0
except Exception:
pass
IOW
with GENERATOR():
BLOCK
becomes a macro call, and GENERATOR() becomes a macro definition; its
body is the macro expansion with "yield" replaced by BLOCK. But in
order to get those semantics, it must be possible for __exit__() to
signal that the exception passed into it should *not* be re-raised.
The current expansion uses roughly this:
finally:
ctx.__exit__(*exc)
and here the finally clause will re-raise the exception (if there was one).
I ran into this when writing unit tests for @contextmanager.
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev
mailing list