Ответ 1
Взгляните на pylint/epylint.py
, который содержит два разных способа запуска pylint программно.
Вы также можете просто вызвать:
from pylint.lint import Run
Run(['--errors-only', 'myfile.py'])
например.
Я хотел бы вызвать средство проверки 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
или другое программное обеспечение: не стесняйтесь предлагать альтернативы. спасибо!
Взгляните на pylint/epylint.py
, который содержит два разных способа запуска pylint программно.
Вы также можете просто вызвать:
from pylint.lint import Run
Run(['--errors-only', 'myfile.py'])
например.
У меня такая же проблема в последнее время.
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 раза быстрее в моем случае. С этим я прошел весь проект, используя полный вывод, чтобы проверить каждый исходный файл, указать ошибки и ранжировать все файлы из их примечания.
Я рад, что наткнулся на это. Я использовал некоторые из ответов здесь и некоторые инициативы, чтобы придумать:
# 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" ]
Вместо создания класса 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'))
Источник:
Другой точкой входа для 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 будет выполнять сам синтаксический анализ и будет правильно выводить ожидаемые результаты в стандартный вывод.
ПРИМЕЧАНИЕ. В какой-то момент pylint
изменил интерфейс. Приведенные выше примеры должны заменить exit=False
на do_exit=False
. (@mad7777, @amit-tripathi)
(Изучено в соответствии с https://github.com/carsongee/pytest-pylint/issues/80)
Вот обертка, которую я использую для программного вызова 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)