New submission from Garrett Berg <googb...@gmail.com>: # Summary In python (2 or 3) it should always be valid to have a bare *raise* statement in an exception block.
try: do_something() except SomeException: do_cleanup() raise # always reraises SomeException with original stack trace You can see this in the python exception documentation: https://docs.python.org/2.7/tutorial/errors.html#raising-exceptions # Reproduction of Failure of invariants Example python file where this doesn't work: from __future__ import print_function import sys def doclear(): """This should basically be a noop""" sys.exc_clear() try: 1/0 except ZeroDivisionError: exc = sys.exc_info()[0] print("first exc:", exc) assert exc is ZeroDivisionError try: 1/0 except ZeroDivisionError: exc = sys.exc_info()[0] print("second exc (before doclear):", exc) doclear() exc = sys.exc_info()[0] print("second exc (after doclear):", exc) assert sys.exc_info()[0] is ZeroDivisionError # fails Running in python2.7 gives: first exc: <type 'exceptions.ZeroDivisionError'> second exc (before doclear): <type 'exceptions.ZeroDivisionError'> second exc (after doclear): None Traceback (most recent call last): File "doclear.py", line 23, in <module> assert sys.exc_info()[0] is ZeroDivisionError # fails AssertionError # Conclusion There seems to be a bug in python 2.7 where it doesn't follow it's own spec. [sys.exc_clear()](https://docs.python.org/2/library/sys.html#sys.exc_clear) states: > This function clears all information relating to the current or last > exception that occurred in the current thread. After calling this function, > exc_info() will return three None values until another exception is raised in > the current thread or *the execution stack returns to a frame where another > exception is being handled*. The above code is clear example where sys.exc_clear() is changing the value of sys.exc_info() *in a different stack frame*, which is against what is stated in the above docs. This bug makes it impossible to reraise with a bare raise statement when doing cleanup that could use sys.exc_clear(). In other words, calling into functions can *change your local state* with regards to what exception is being handled. ---------- components: Interpreter Core messages: 308264 nosy: Garrett Berg priority: normal severity: normal status: open title: sys.exc_clear() clears exception in other stack frames type: behavior versions: Python 2.7 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue32317> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com