msg66713 - (view) |
Author: Dmitry Dvoinikov (ddvoinikov) |
Date: 2008-05-12 07:06 |
If a context manager is used within exception handling block, the active exception is silenced after the context block completes and __exit__ exits. try: raise Exception("foo") except: with SomeContextManager(): pass raise # in Py2.5 throws 'foo', in Py3.0 fails with RuntimeError |
|
|
msg66724 - (view) |
Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) *  |
Date: 2008-05-12 14:20 |
This problem was introduced by r62847. |
|
|
msg66775 - (view) |
Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) *  |
Date: 2008-05-13 09:10 |
Note that the problem is not related to "with", but with nested exception handlers: try: raise Exception("foo") except: try: pass except: pass raise # in Py2.5 throws 'foo', in Py3.0 fails with RuntimeError OTOH, python has always had poor support for nested exceptions; tried with python24 and python25:: try: raise Exception("foo") except: try: raise KeyError("caught") except KeyError: pass raise # reraise the KeyError... This does not happen if the two lines with KeyError are moved in another function. |
|
|
msg66791 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2008-05-13 18:36 |
I've just discovered that the patch in r62847 doesn't clean up the exception state if the except clause does not mention a local variable, e.g. "except MyException" instead of "except MyException as e". |
|
|
msg66794 - (view) |
Author: Georg Brandl (georg.brandl) *  |
Date: 2008-05-13 19:22 |
Raising priority. |
|
|
msg66811 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2008-05-14 09:21 |
As Amaury said, lexically nested exception handlers make re-raising behaviour buggy. In Py3k, a workaround is to instead write: try: raise Exception("foo") except Exception as : try: raise KeyError("caught") except KeyError: pass raise e With the slight inconvenience that the "raise e" line will be appended to the original traceback. If we want bare "raise" statements to work as expected after a nested exception handler, we'll need to add proper exception stacking, for example by adding the exception value as a member of PyTryBlock. The effect on performance should also be measured. |
|
|
msg66812 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2008-05-14 09:22 |
Small typo in the snippet above, this should obviously read: try: raise Exception("foo") except Exception as e: try: raise KeyError("caught") except KeyError: pass raise e |
|
|
msg67302 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2008-05-24 14:13 |
Just found another funny example. This one fails also before r62847. def except_yield(): try: raise Exception("foo") except: yield 1 raise list(except_yield()) In Py3k (with or without r62487), we get "RuntimeError: No active exception to reraise". In Python 2.5, we get "TypeError: exceptions must be classes, instances, or strings (deprecated), not NoneType". |
|
|
msg67600 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2008-06-01 20:05 |
A clean solution to both #2507 and #2833 is now proposed in #3021. |
|
|
msg67991 - (view) |
Author: Benjamin Peterson (benjamin.peterson) *  |
Date: 2008-06-11 16:04 |
Fixed in r64121. |
|
|