invoking pylint programmatically

时光总嘲笑我的痴心妄想 提交于 2019-11-27 18:44:52
syt

Take a look at the pylint/epylint.py which contains two different ways to start pylint programatically.

You can also simply call :

from pylint.lint import Run
Run(['--errors-only', 'myfile.py']) 

for instance.

I got the same problem recently. syt is right, pylint.epylint got several methods in there. However they all call a subprocess in which python is launched again. In my case, this was getting quite slow.

Building from mcarans answer, and finding that there is a flag exit, I did the following

class WritableObject(object):
    "dummy output stream for pylint"
    def __init__(self):
        self.content = []
    def write(self, st):
        "dummy write"
        self.content.append(st)
    def read(self):
        "dummy read"
        return self.content
def run_pylint(filename):
    "run pylint on the given file"
    from pylint import lint
    from pylint.reporters.text import TextReporter
    ARGS = ["-r","n", "--rcfile=rcpylint"]  # put your own here
    pylint_output = WritableObject()
    lint.Run([filename]+ARGS, reporter=TextReporter(pylint_output), exit=False)
    for l in pylint_output.read():
        do what ever you want with l...

which is about 3 times faster in my case. With this I have been going through a whole project, using full output to check each source file, point errors, and rank all files from their note.

mcarans

I'm glad I came across this. I used some of the answers here and some initiative to come up with:

# a simple class with a write method
class WritableObject:
    def __init__(self):
        self.content = []
    def write(self, string):
        self.content.append(string)
pylint_output = WritableObject()

pylint = lint.Run(args, reporter=ParseableTextReporter(pylint_output), exit=False)

Args in the above is a list of strings eg. ["-r", "n", "myfile.py"]

Amit Tripathi

Instead of creating a WritableObject class we can use StringIO. StringIO contains write method.

import sys
try:
    from io import StringIO
except:
    from StringIO import StringIO

stdout = sys.stdout
sys.stdout = StringIO()

ARGS = ["-r","n", "--rcfile=rcpylint"]
r = lint.Run(['../test.py']+ARGS, exit=False)

test = sys.stdout.getvalue()
sys.stdout.close()
sys.stdout = stdout

print (test.split('\n'))

Source:

Another entry point for pylint is the epylint.py_run function, that implement the stdout and stderr interception. However, as shown in the following code, pylint seems to not write its reports in stdout:

from pylint import epylint

pylint_stdout, pylint_stderr = epylint.py_run(__file__, return_std=True)
print(pylint_stdout.getvalue())  # -> there is just the final rank, no report nor message
print(pylint_stderr.getvalue())

Now, i found that pylint from API and pylint from CLI do not use the same default parameters. So, you just have to provides the parameters you need to pylint.

from pylint import epylint
options = '--enable=all'  # all messages will be shown
options += '--reports=y'  # also print the reports (ascii tables at the end)

pylint_stdout, pylint_stderr = epylint.py_run(__file__ + ' ' + options, return_std=True)
print(pylint_stdout.getvalue())
print(pylint_stderr.getvalue())

As described here, pylint will perform the parsing itself, and will correctly output the expected results in stdout.

NOTE: At some point pylint changed the interface. The above examples need to replace exit=False with do_exit=False. (@mad7777, @amit-tripathi)

(Learned as per https://github.com/carsongee/pytest-pylint/issues/80)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!