On Fri, Feb 07, 2020 at 09:57:18AM -0800, Andrew Barnert via Python-ideas wrote:
However, Shai Berger had an interesting idea in that Django thread: treat a `raise` directly under an `except` block special. For example:
except ZeroDivisionError: raise ValueError('whatever') # would produce a chaining error message
Let's get the terminology right: exceptions inside an except block are always chained unless you explicitly disable the chaining with an excplit "raise SpamError() from None".
Excluding the "from None" case, any exception raised inside a except block will have its `__context__` set. That's how you get chaining. The difference between the "During handling of the above exception" and "The above exception was the direct cause" messages comes down to whether or not the `__cause__` is set.
The status quo requires you to set the cause explicitly:
except ZeroDivisionError as error: raise ValueError('whatever') from error
Shai Berger wants to set it implicily, based on where the raise is. If it is "directly" under the except line, implicitly set the cause.
It seems like a truly bad idea to change the semantics of the exception depending on which of these I happen to write:
# exception with __cause__ magically set except ZeroDivisionError: raise ValueError(generate_long_exception_text())
# exception with __context__ set but not __cause__ except ZeroDivisionError: msg = generate_long_exception_text() raise ValueError(msg)
Having the raise directly under the except line is a special case of the more general case where the raise is *somewhere* in a multi-line except block. I'm pretty sure the Zen of Python has a relevent koan here about changing the rules for special cases...
There might be other problems I’m not seeing here. But it seems at least worth exploring.
Why? What actual problem is this trying to fix, aside from Ram's aethetic taste that he wants the message to read
The above exception was the direct cause of the following exception
instead of the default
During handling of the above exception, another exception occurred
between exception contexts?
The status quo takes the conservative position that an exception inside an except block may not be directly caused by the caught exception. which is reasonable. The traceback only claims a direct cause if the developer explicitly sets the cause, but it still shows the context regardless of whether the cause is set or not.
In terms of debugging, we see precisely the same traceback, the only difference is whether or not the interpreter states that one exception caused the other or not.