Never pass a tuple to raise
. It won't do what you expect.
On both Python 2 and Python 3, raise
is documented to not accept a tuple. However, Python 2 has a weird code path in the raise
implementation where if the first (or only) argument to raise
is a tuple, it will be repeatedly replaced with its first element until Python reaches something that isn't a tuple. I have no idea why this is a thing, but it means that something like
raise ((Exception,), "other", "tuple", "items", "get", "ignored")
gets treated like
raise Exception
Here's a demo. Python 3 behaves more sensibly, erroring out because a tuple isn't an exception.
The syntax for raising exceptions changed on Python 3. The Python 2 statement
raise ExceptionType, value, traceback
is now
raise ExceptionType(value).with_traceback(traceback)
or, if value
is an instance of ExceptionType
,
raise value.with_traceback(traceback)
Unfortunately, these syntaxes are incompatible to the degree that you can't even write both and pick which one to run based on your Python version. You'll get a syntax error before your code even runs.
The easiest way to fix this is with a compatibility library. For example, with six.reraise
:
six.reraise(ExceptionType, value, traceback)