invoquer pylint de manière programmatique
j'aimerais invoquer le pylint checker, limité à l'Erreur de signalisation, dans le cadre de mes tests unitaires. donc j'ai vérifié le script exécutable de pylint, j'ai eu le pylint.lint.Run
classe d'aide et là je me suis perdu dans un assez long __init__
fonction, se terminant par un appel à sys.exit()
.
quelqu'un a déjà essayé et réussi à le faire?
le rêve-plan serait ceci:
if __name__ == '__main__':
import pylint.lint
pylint.lint.something(__file__, justerrors=True)
# now continue with unit testing
tous les conseils? autre que "copier l' __init__
méthode et sauter le sys.exit()
", je signifie?
je n'ai pas l' besoin les tests à exécuter par pylint
, il pourrait aussi bien être pyflakes
ou autre logiciel: n'hésitez pas à suggérer des alternatives. merci!
5 réponses
regardez pylint/epylint.py
qui contient deux différentes façons de démarrer pylint de façon programmatique.
Vous pouvez aussi tout simplement appeler :
from pylint.lint import Run
Run(['--errors-only', 'myfile.py'])
par exemple.
j'ai eu le même problème récemment.
syt est droit, pylint.epylint
a plusieurs méthodes. Cependant, ils appellent tous un sous-processus dans lequel python est lancé à nouveau. Dans mon cas, c'est assez lent.
construction à partir de la réponse de mcarans, et constatant qu'il y a une sortie de drapeau, j'ai fait ce qui suit
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...
je suis content d'être tombé là-dessus. J'ai utilisé certaines des réponses ici et d'un peu d'initiative à venir avec:
# 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 dans ce qui précède est une liste de chaînes par exemple. ["- r", "n", "myfile.py"]
au lieu de créer une classe WritableObject, nous pouvons utiliser StringIO. StringIO contient la méthode d'écriture.
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:
un autre point d'entrée pour pylint est le epylint.py_run
fonction, qui implémente l'interception stdout et stderr. Cependant, comme le montre le code suivant, pylint ne semble pas écrire ses rapports dans 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())
maintenant, j'ai trouvé que pylint de L'API et pylint de CLI n'utilisent pas les mêmes paramètres par défaut. Donc, vous avez juste à fournit les paramètres dont vous avez besoin 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())
Comme décrit ici, pylint effectuera l'analyse elle-même, et produira correctement les résultats attendus dans stdout.