0

Can somebody please explain if why or why not 'raise a,b,c,' and 'raise (a,b,c)' are same in Python 2.7.

I tried to find information on how Tuples are treated from here and here but I couldn't establish if I could use the above expressions in place of one another.

Here is some background. I have a Python 2 code which is having a lot of following statements

raise e,v,t

Python 3 gives error on this syntax. Converting it to following gets away the Python 3 compiler error but I wanted to verify if intent remains same in both Python 2 as well as Python 3.

raise (e,v,t)
user2357112
  • 260,549
  • 28
  • 431
  • 505
ViFI
  • 971
  • 1
  • 11
  • 27
  • 2
    Did you try them? Did you get the same result? – AChampion Mar 30 '17 at 19:13
  • 1
    https://stackoverflow.com/questions/34463087/raise-exception-in-python-2-x-and-3-x/40877934 https://stackoverflow.com/questions/5497013/convert-code-from-python-2-x-to-3-x/5497070 – Josh Lee Mar 30 '17 at 19:15
  • 1
    Did you try to check the Python3 [docs](https://docs.python.org/3.5/reference/simple_stmts.html#grammar-token-raise_stmt)? – juanpa.arrivillaga Mar 30 '17 at 19:16
  • @AChampion : I tried `x = 1,2,3` and `x =(1,2,3)` in python interpreter and got 'type(x)' as same that's why I had confusion if it is a safe change. – ViFI Mar 30 '17 at 19:20
  • In other words, no it is not the same. In fact in Python 3 if you ever execute that line, you'll get an error, because it will try to call that instance (which is a tuple), and you can only `raise` objects that derive from `BaseException` – juanpa.arrivillaga Mar 30 '17 at 19:20

2 Answers2

1

raise has never taken a tuple as a parameter. In Python 2, the syntax was such that it looked like a tuple, which is where your confusion is coming from. There was a drastic syntax change for Python 3, where the redundant exception class type was removed and the keyword from is used in place of a comma.

In Python 2:

raise a, b, c

Becomes in Python 3:

raise b.with_traceback(c)
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • You've gotten the exception chaining syntax mixed up with the syntax for alternate tracebacks. The way to pick a different traceback is the [`with_traceback`](https://docs.python.org/3/library/exceptions.html#BaseException.with_traceback) method, so it's `raise a(b).with_traceback(c)`, or `raise b.with_traceback(c)` if `b` is already an instance of `a` (or one of a few other variants, because Python 2 has a lot of ways to interpret the second `raise` argument). [`from` is for one exception being caused by another](https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement). – user2357112 Mar 30 '17 at 20:42
  • @user2357112 thanks, I was misreading the documentation. I've never actually tried raising anything other than a simple `Exception` class myself. – Mark Ransom Mar 30 '17 at 21:00
1

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)
user2357112
  • 260,549
  • 28
  • 431
  • 505