1

I'm looking at this minimal valid(?) program:

import sys

def f():
    try:
        raise Exception()
    except Exception:
        raise Exception(), None, sys.exc_info()[2]

f()

This program executes and behaves as expected , preserving the stack trace of the inner exception, as documented by help("raise"). However, when I run pylint on it, this is what I get:

$ pylint program.py 
************* Module tmp
E:  7, 0: invalid syntax (<string>, line 7) (syntax-error)

The syntax-error disappears when I remove the second and third expressions to raise.

Is this a bug in pylint, or am I overlooking something?

loopbackbee
  • 21,962
  • 10
  • 62
  • 97

1 Answers1

2

Your pylint binary testing for Python 3 syntax, your code is valid for Python 2 only. Pylint tests code following the syntax of the Python binary you installed it with (it uses Python's own parser).

In Python 3, you'd use:

raise Exception().with_traceback(sys.exc_info()[2])

See the raise statement documentation for Python 3.

While your syntax may be correct for Python 2, you are technically using raise wrong. When passing in 3 elements, the first must be a class, not an instance. The second is an instance of that class, the third the traceback:

raise Exception, Exception(), sys.exc_info()[2]

or you can pass in None for an empty argument list passed to the first (the class) to create an instance:

raise Exception, None, sys.exc_info()[2]

Your code still happens to work, but only because Python isn't being too strict and takes that first argument as the instance when it is not a class.

If you want to test Python 2 code with pylint, install a copy into your Python 2 binary, and run that version. See Specify which python version pylint should evaluate for

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • I completely forgot how I had installed pylint with python3, thank you! Regarding using `raise` wrong, the documentation on my machine explicitly states that `If the first object is an instance, the type of the exception is the class of the instance, the instance itself is the value, and the second object must be "None".`. Did this happen to change across versions? – loopbackbee Sep 25 '17 at 15:27