python 以编程方式调用 pylint

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2028268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:36:34  来源:igfitidea点击:

invoking pylint programmatically

pythoncoding-styleautomated-testspylint

提问by mariotomo

I'd like to invoke the pylint checker, limited to the Error signalling part, as part of my unit testing. so I checked the pylint executable script, got to the pylint.lint.Runhelper class and there I got lost in a quite long __init__function, ending with a call to sys.exit().

我想调用 pylint 检查器,仅限于错误信号部分,作为我的单元测试的一部分。所以我检查了 pylint 可执行脚本,进入了pylint.lint.Runhelper 类,在那里我迷失在一个很长的__init__函数中,以调用sys.exit().

anybody ever tried and managed to do so?

有人曾尝试并设法这样做吗?

the dream-plan would be this:

梦想计划是这样的:

if __name__ == '__main__':
  import pylint.lint
  pylint.lint.something(__file__, justerrors=True)
  # now continue with unit testing

any hints? other than "copy the __init__method and skip the sys.exit()", I mean?

任何提示?除了“复制__init__方法并跳过sys.exit()”,我的意思是?

I don't needthe tests to be run by pylint, it might as well be pyflakesor other software: feel free to suggest alternatives. thanks!

我并不需要通过运行测试pylint,它也可能是pyflakes或其他软件:随时提出替代方案。谢谢!

采纳答案by syt

Take a look at the pylint/epylint.pywhich contains twodifferent ways to start pylint programatically.

看看pylint/epylint.py包含两种不同的以编程方式启动 pylint 的方法的 。

You can also simply call :

您也可以简单地调用:

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

for instance.

例如。

回答by mad7777

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

我最近遇到了同样的问题。syt 是对的,里面pylint.epylint有几种方法。但是,它们都调用了一个子进程,在该子进程中再次启动了 python。就我而言,这变得非常缓慢。

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

从 mcarans 答案中构建,并发现有一个标志出口,我做了以下

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.

就我而言,这大约快 3 倍。有了这个,我已经完成了整个项目,使用完整的输出来检查每个源文件,指出错误,并从他们的笔记中对所有文件进行排名。

回答by Amit Tripathi

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

我们可以使用 StringIO 代替创建 WritableObject 类。StringIO 包含 write 方法。

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:

来源:

回答by 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"]

上面的 Args 是一个字符串列表,例如。["-r", "n", "myfile.py"]

回答by aluriak

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

pylint 的另一个入口点是epylint.py_run实现 stdout 和 stderr 拦截的函数。但是,如以下代码所示,pylint 似乎没有在 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.

现在,我发现 API 中的 pylint 和 CLI 中的 pylint 不使用相同的默认参数。因此,您只需要提供 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.

如上所述这里,pylint的将执行解析本身,并准确地将输出在标准输出的预期结果。

回答by mcallaghan-bsm

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

注意:在某些时候pylint改变了界面。上面的例子需要替换exit=Falsedo_exit=False. (@mad7777,@amit-tripathi)

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

(根据https://github.com/carsongee/pytest-pylint/issues/80学习)

回答by Constantin De La Roche

Here is a wrapper I use to programmatically call pylint so I have a --fail-under arg to overwite the default pylint exit code (usefull for CI). This snippet was tested using pylint 2.3.1

这是我用来以编程方式调用 pylint 的包装器,因此我有一个 --fail-under arg 来覆盖默认的 pylint 退出代码(对 CI 有用)。此代码段已使用 pylint 2.3.1 进行测试

""" Execute pylint and fail if score not reached. """
import argparse
import sys
from pylint import lint

desc = "PyLint wrapper that add the --fail-under option."\
       " All other arguments are passed to pylint."
parser = argparse.ArgumentParser(description=desc, allow_abbrev=False)
parser.add_argument('--fail-under', dest='threshold', type=float, default=8,
                    help='If the final score is more than THRESHOLD, exit with'
                    ' exitcode 0, and pylint\'s exitcode otherwise.')

args, remaining_args = parser.parse_known_args()

threshold = args.threshold

run = lint.Run(remaining_args, do_exit=False)
score = run.linter.stats['global_note']

if score < threshold:
    sys.exit(run.linter.msg_status)