Skip to content
rebeccakay edited this page Oct 29, 2016 · 35 revisions

Purpose of Reporters in Pylint

Reporters display messages when they are available. Each of the messages focuses on a particular aspect of the project, such as number of messages by categories. Right after, a global evaluation of the code is evaluated. A pylint reporter is responsible for storing and reporting error messages.

Taken from pylint.readthedocs.io

For instance, the metrics report displays summaries gathered from the current run.

  • the number of processed modules
  • for each module, the percentage of errors and warnings
  • the total number of errors and warnings
  • percentage of classes, functions and modules with docstrings, and a comparison from the previous run
  • percentage of classes, functions and modules with correct name (according to the coding standard), and a comparison from the previous run
  • a list of external dependencies found in the code, and where they appear

More information about Pylint and reporters in Pylint:

Usage of Reporters in PyTA

When a user calls python_ta.check_all() to check a piece of code, ColorReporter and PlainReporter are also called and they:

    1. Piggyback on methods in Pylint
    1. Overwrite the way PyLint reports errors to messages that are easier to read (Print statement)

Reporters in PyTA allow you to:

  • Print into HTML, something Pylint doesn't support anymore. It uses JSON now.
  • Differentiate between errors as they are separated into two categories (Error and Style). Errors are also visually pleasing.
  • Look at numbers and percentages, for each individual and the entire class/section.

An overview of the distribution, by providing the mean and the Five Number Summary (Max, Upper Quartile (Q3), Median, Lower Quartile (Q1), Min). For example, if Mean > Median, how might the graph look?

Answer: Positively skewed.

More information about python_ta.check_all() and PyTA's custom reporters:

Methods that should be implemented for every reporter

If your reporters are subclasses of BaseReporter, there are two main methods you should consider in addition to the instance method.

  • instance(self) You should initialize an empty list here to store the messages for later use.

  • handle_message(self, msg) This method lets you handle the given msg obg. handle_message must be overwritten from Pylint's default handle_message in your own reporter should you choose to use MessagesHandlerMixIn's very useful method add_message. This is because at the very end, the following lines are executed:

From pylint/pylint/utils.py:

 self.reporter.handle_message(Message(msgid, symbol, (abspath, path, module, obj, line or 1, col_offset or 0), msg, confidence))

BaseReporter expects that its subclasses will each have its own handle_message function.

  • _display(self, layout) Essentially, what do you want to do with all the data? How do you want to display what you have collected? This should be implemented if you plan on using BaseReporter's display_reports method, which is useful for if you want to show the children in the Tree. However, if you choose not to continue with BaseChecker's Tree, you could rewrite this into a "print_messages" method.

From pylint/reporters/init.py:

def display_reports(self, layout):
    """display results encapsulated in the layout tree"""
    self.section = 0
    if hasattr(layout, 'report_id'):
        layout.children[0].children[0].data += ' (%s)' % layout.report_id
    self._display(layout)

Methods that can be implemented for every reporter

In addition to what are already shown in BaseReporter and JsonReporter, here are some suggestions of methods you might want to consider:

They can:

  • reset the reporter
  • print messages (as an alternative/addition to _display)
  • sort messages
  • handle coding errors only
  • handle style errors only

Examples of above 3 implementation can be found here.

How is a reporter notified of an error?

As previously mentioned, when a user calls python_ta.check_all() to check a piece of code, ColorReporter and PlainReporter are also called, which means BaseReporter is called eventually.

These are the steps from collecting errors to eventually displaying them in PyTA.

  • Under _check, current_reporter initializes ColorReporter
  • ColorReporter is set to PyLinter's reporter param
  • The checkers get to work. Please refer to Checkers for more information
  • linter.check utilizes self.add_message
  • self.add_message from utils.py activates handle_message, which in PyTA's case is under PlainReporter
  • PlainReporter stores the Message types like this: self.reporter.handle_message(Message(msgid, symbol,(abspath, path, module, obj, line or 1, col_offset or 0), msg, confidence))
  • Then we switch back to python_ta's _init_ and print current_reporter's messages
  • Because current_reporter is the class ColorReporter which is a subclass of PlainReporter, all of this can be accessed through ColorReporter and bam we're done!