programowo wywoływanie pylint

W ramach moich testów jednostkowych chciałbym wywołać kontroler pylint, ograniczony do części sygnalizacji błędów. sprawdziłem skrypt wykonywalny pylint, dotarłem do klasy helpera pylint.lint.Run i tam zgubiłem się w dość długiej funkcji __init__, zakończonej wywołaniem do sys.exit().

Ktoś próbował i udało się to zrobić?

Wymarzony plan byłby taki:

if __name__ == '__main__':
  import pylint.lint
  pylint.lint.something(__file__, justerrors=True)
  # now continue with unit testing
Jakieś wskazówki? inne niż " skopiuj metodę __init__ i pomiń metodę sys.exit()", mam na myśli?

I don ' t need the testy prowadzone przez pylint, równie dobrze może to być pyflakes lub inne oprogramowanie: sugeruj alternatywy. dzięki!

Author: mariotomo, 2010-01-08

5 answers

Spójrz na pylint/epylint.py, który zawiera dwa różne sposoby uruchamiania programu pylint.

Możesz również po prostu zadzwonić:
from pylint.lint import Run
Run(['--errors-only', 'myfile.py']) 
Na przykład.
 20
Author: syt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-31 14:30:13

Ostatnio mam ten sam problem. syt ma rację, pylint.epylint ma tam kilka metod. Jednak wszystkie one nazywają podproces, w którym python jest uruchamiany ponownie. W moim przypadku robiło się to dość powolne.

Budynek od mcarans odpowiedz, i stwierdziwszy, że jest wyjście z flagi, zrobiłem następujące

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...
Co w moim przypadku jest około 3 razy szybsze. Z tym przechodziłem przez cały projekt, używając pełnego wyjścia, aby sprawdzić każdy plik źródłowy, wskazać błędy i uszeregować wszystkie pliki z ich liścik.
 16
Author: mad7777,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-27 17:06:39

Cieszę się, że na to wpadłam. Skorzystałem z kilku odpowiedzi tutaj i trochę inicjatywy, aby wymyślić:

# 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 w powyższej liście jest lista łańcuchów np. ["- r", "n", "myfile.py"]

 3
Author: mcarans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-12 14:40:05

Zamiast tworzyć klasę WritableObject możemy użyć StringIO. StringIO zawiera metodę zapisu.

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

Źródło:

 2
Author: Amit Tripathi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:32:35

Kolejnym punktem wejścia dla pylint jest funkcja epylint.py_run, która implementuje przechwytywanie stdout i stderr. Jednak, jak pokazano w poniższym kodzie, pylint wydaje się nie pisać swoich raportów w 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())

Teraz odkryłem, że pylint z API i pylint z CLI nie używają tych samych domyślnych parametrów. Musisz więc podać parametry, których potrzebujesz, aby pylintować.

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

Jak opisano tutaj , pylint wykona parsowanie i poprawnie wyświetli oczekiwane wyniki w chorobie wenerycznej.

 1
Author: aluriak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-16 08:45:01