2

When i use pylint:

import pylint.lint
options = [
    filename, 
    "--output-format=json"
]
results = pylint.lint.Run(options, do_exit=False)
messages = results.linter.reporter.messages

My messages variable has the correct informations as JSON. However, pylint prints the JSON message in the console...

How can i prevent print() of pylint ?

This option doesn't work:

options = [
    filename, 
    "--output-format=json",
    "--reports=no"    # Tells whether to display a full report or only the messages.
]

see https://pylint.readthedocs.io/en/stable/technical_reference/features.html#reports-options

Rod
  • 712
  • 2
  • 12
  • 36

5 Answers5

5

The only way to do it well... is to use your ReporterClass.

import pylint.lint
options = [
    filename, 
    "--output-format=mypackage.mymodule.MyReporterClass" 
]
results = pylint.lint.Run(options, do_exit=False)
messages = results.linter.reporter.messages

The code below has the same behavior as json but its display_messages method does nothing

import html
from pylint.interfaces import IReporter
from pylint.reporters import *

class MyReporterClass(BaseReporter):
    """Report messages and layouts."""

    __implements__ = IReporter
    name = "myreporter"
    extension = "myreporter"

    def __init__(self, output=sys.stdout):
        BaseReporter.__init__(self, output)
        self.messages = []

    def handle_message(self, msg):
        """Manage message of different type and in the context of path."""
        self.messages.append(
            {
                "type": msg.category,
                "module": msg.module,
                "obj": msg.obj,
                "line": msg.line,
                "column": msg.column,
                "path": msg.path,
                "symbol": msg.symbol,
                "message": html.escape(msg.msg or "", quote=False),
                "message-id": msg.msg_id,
            }
        )

    def display_messages(self, layout):
        """Do nothing."""

    def display_reports(self, layout):
        """Do nothing."""

    def _display(self, layout):
        """Do nothing."""


def register(linter):
    """Register the reporter classes with the linter."""
    linter.register_reporter(MyReporterClass)

PyLint will no longer do print() after evaluating the code.

Rod
  • 712
  • 2
  • 12
  • 36
  • The shorter way will just be to override the method: `pylint.lint.reporters.json_reporter.JSONReporter.display_messages = lambda self, layout: None` – Ron Serruya Jun 01 '20 at 13:55
1

The only way I found is to comment out the line:

self.reporter.display_messages(report_nodes.Section())

from \pylint\lint.py

Giampietro Seu
  • 786
  • 9
  • 16
1

You can easily use the capturing stdout for a given command, to suppress the printed output

import pylint.lint
filename = "server.py"
options = [
    filename,
    "--output-format=json"
]

import contextlib
@contextlib.contextmanager
def capture():
    import sys
    from io import StringIO
    oldout,olderr = sys.stdout, sys.stderr
    try:
        out=[StringIO(), StringIO()]
        sys.stdout,sys.stderr = out
        yield out
    finally:
        sys.stdout,sys.stderr = oldout, olderr
        out[0] = out[0].getvalue()
        out[1] = out[1].getvalue()

with capture() as out:
    results = pylint.lint.Run(options, do_exit=False)
messages = results.linter.reporter.messages

You can see many other approaches discussed in

Capture stdout from a script in Python

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
1

You could also use the CollectingReporter, and then convert to JSON yourself.

HINT: Note that you need to disable scoring, otherwise CollectingReporter creates an error, because it doesn't have a display function.

from pylint.reporters import CollectingReporter
from pylint.lint import Run
rep = CollectingReporter()
Run([filename, "-sn"], reporter=rep, do_exit=False)
# Now continue processing rep.messages
CodeMonkey
  • 4,067
  • 1
  • 31
  • 43
0

I realize this is a late answer, but I thought I'd mention that there is an alternative in between rolling your own reporter and redirecting stdout. Unfortunately it's not very well documented, but a quick look at the code shows that the BaseReporter class has a set_output method which seems to be designed exactly for this. So another approach which allows suppression of stdout but still gathers the JSON output (I use it for selective reporting) is something like this:

from io import StringIO
import pylint.lint
from pylint.reporters import JSONReporter

out_stream = StringIO()
quiet_reporter = JSONReporter()
quiet_reporter.set_output(out_stream)

results = pylint.lint.Run([filename], reporter=quiet_reporter, do_exit=False)

Then you can use results.linter.stats to make decisions about what to report (e.g., stats['refactor'] holds the number of refactor messages generated), and you can print or log out_stream as you see fit.

RishiG
  • 2,790
  • 1
  • 14
  • 27