Search code examples
pythonexceptionpylintraise

pylint syntax error on valid program (raise with three arguments / expressions)


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?


Solution

  • 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