Подтвердить что ты не робот

Программный вызов pylint

Я хотел бы вызвать средство проверки pylint, ограниченное частью сигнализации об ошибке, как часть моего модульного тестирования. поэтому я проверил исполняемый файл pylint script, попал в вспомогательный класс pylint.lint.Run, и там я потерялся в довольно длинной функции __init__, заканчивая вызовом sys.exit().

кто-нибудь когда-либо пробовал и сумел это сделать?

план мечты был бы следующим:

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

любые подсказки? кроме "скопировать метод __init__ и пропустить sys.exit()", я имею в виду?

Мне не нужны тесты, которые будут выполняться pylint, это может быть pyflakes или другое программное обеспечение: не стесняйтесь предлагать альтернативы. спасибо!

4b9b3361

Ответ 1

Взгляните на pylint/epylint.py, который содержит два разных способа запуска pylint программно.

Вы также можете просто вызвать:

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

например.

Ответ 2

У меня такая же проблема в последнее время. syt прав, pylint.epylint получил несколько методов. Однако все они называют подпроцессом, в котором python запускается снова. В моем случае это происходило довольно медленно.

Построение ответа из 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...

что примерно в 3 раза быстрее в моем случае. С этим я прошел весь проект, используя полный вывод, чтобы проверить каждый исходный файл, указать ошибки и ранжировать все файлы из их примечания.

Ответ 3

Я рад, что наткнулся на это. Я использовал некоторые из ответов здесь и некоторые инициативы, чтобы придумать:

# 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)

Арги в приведенном выше списке представляют собой список строк, например. [ "-r", "n", "myfile.py" ]

Ответ 4

Вместо создания класса WritableObject мы можем использовать StringIO. StringIO содержит метод записи.

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'))

Источник:

Ответ 5

Другой точкой входа для 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())

Теперь я обнаружил, что pylint из API и pylint из CLI не используют одинаковые параметры по умолчанию. Таким образом, вы просто должны предоставить параметры, которые вам нужны для 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())

Как описано здесь, Pylint будет выполнять сам синтаксический анализ и будет правильно выводить ожидаемые результаты в стандартный вывод.

Ответ 6

ПРИМЕЧАНИЕ. В какой-то момент pylint изменил интерфейс. Приведенные выше примеры должны заменить exit=False на do_exit=False. (@mad7777, @amit-tripathi)

(Изучено в соответствии с https://github.com/carsongee/pytest-pylint/issues/80)

Ответ 7

Вот обертка, которую я использую для программного вызова pylint, поэтому у меня есть аргумент --fail-under, чтобы перезаписать код выхода по умолчанию для 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\ 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)