# loki.lint.reporter module

class ProblemReport(msg, location)

  Bases: `object`

  Data type to represent a problem reported for a node in the IR

  Parameters:

    - msg (str) – The message describing the problem.

    - location (`Sourcefile` or `Module` or `Subroutine` or `Node`) – The IR component in which the problem exists.

class RuleReport(rule, reports=None, disabled=None)

  Bases: `object`

  Container type to collect all individual problems reported by a rule

  All `RuleReport` instances that belong to a file are collected in a `FileReport`.

  Parameters:

    - rule (`GenericRule`) – The rule that generated the report

    - reports (list of `ProblemReport`, optional) – List of problem reports for this rule

    - disabled (bool or list, optional) – Flag to disable reporting of this rule. If set to True, no violations will be reported. If a list of hashes is provided, the first line of a violation will be compared against these hashes and not reported if found.

  add(msg, location)

    Convenience function to append a problem report to the list of problems reported by the rule.

    Parameters:

      - msg (str) – The message describing the problem.

      - location (`Sourcefile` or `Module` or `Subroutine` or `Node`) – The IR node or expression node in which the problem exists.

class FileReport(filename, hash=None, reports=None)

  Bases: `object`

  Container type to collect all rule reports for a file

  Parameters:

    - filename (str) – The filename of the file the report is for

    - hash (str, optional) – Provide a hash for the file’s content to identify the file version

    - reports (list, optional) – List of `RuleReport`.

  add(rule_report)

    Append a rule report to the list of reports.

    Parameters:

      rule_report (`RuleReport`) – The report to be stored.

  property fixable_reports

    Yield only those rule reports that belong to a rule that can be fixed.

class Reporter(handlers=None)

  Bases: `object`

  Manager for problem reports and their handler.

  It collects file reports and feeds them to all available handlers to generate their individual reporting pieces. Note that this processing of reports happens immediately when adding a new file report for two reasons:

  1. Enable immediate output functionality (i.e., being able to print problems as soon as they are detected and not only at the very end of a (lengthy) multi file parser run.

  2. To allow parallel processing. The location of problem reports is not pickable and thus they need to be processed into a pickable form.

  The class maintains a dict in which a list of reports is stored for each handler. In a parallel setting, this needs to be initialized explicitly to enable thread safe data structures by calling init_parallel().

  Parameters:

    handlers (list) – The enabled handlers. If none given, `DefaultHandler` will be used.

  init_parallel(manager)

    Additional initialization step when using the reporter in a parallel setting.

    Parameters:

      manager (`multiprocessing.Manager`) – The multiprocessing manager that should be used to create thread safe data structures.

  add_file_report(file_report)

    Process a file report in all handlers and store the results.

    :param `FileReport` file_report: the file report to be processed.

  add_file_error(filename, rule, msg)

    Create a file report with a single problem reported and add it.

    This is a convenience function that can be used, e.g., to report a failing rule or other problems with a certain file.

    Parameters:

      - filename (str) – The file name of the corresponding file.

      - rule (`GenericRule`) – The rule that exposed the problem or None.

      - msg (str) – A description of the problem.

  output()

    Call the output function for all reports on every handler.

class GenericHandler(basedir=None)

  Bases: `object`

  Base class for report handler.

  Parameters:

    basedir (str, optional) – Base directory path relative to which file paths are given.

  get_relative_filename(filename)
  format_location(filename, location)

    Create a string representation of the location given in a ProblemReport.

    For a given location it tries to determine:

      - the file name (if not given)

      - the source line

      - the name of the scope (i.e., enclosing subroutine or module)

    Parameters:

      - filename (str) – The file name of the source file.

      - location (`Node` or `Subroutine` or `Sourcefile` or `Module`) – The AST node that triggered the problem report.

    Returns:

      The formatted string in the form “<filename> (l. <line(s)>) [in routine/module …]”

    Return type:

      str

  handle(file_report)

    Handle the given `file_report`.

    This routine has to be implemented by the handler class. It should either print/save the report immediately or return a picklable object that is later to be printed/saved via `output()`.

    Note that the only requirement is that `handle()` and `output()` are compatible in the sense that a list of objects returned by `handle()` can be processed by `output()`.

  output(handler_reports)

    Output the list of report objects created by `handle()`.

class DefaultHandler(target=<bound method Logger.warning of <Logger Loki (WARNING)>>, immediate_output=True, basedir=None)

  Bases: `GenericHandler`

  The default report handler for command line output of problems.

  Parameters:

    - target (optional) – The output destination as a callback. Will be called with a string. Defaults to `loki.logging.logger.warning`

    - immediate_output (bool, optional) – Print problems immediately if True, otherwise collect messages and print when calling output(). Defaults to True

    - basedir (str, optional) – Base directory path relative to which file paths are given.

  fmt_string = '{rule}: {location} - {msg}'
  handle(file_report)

    Creates a string output of all problem reports and (by default) prints them immediately to target.

    Parameters:

      file_report (`FileReport`) – The file report to be processed.

    Returns:

      The list of problem report strings.

    Return type:

      list of str

  output(handler_reports)

    Print all reports to target if immediate_output is disabled.

    Parameters:

      handler_reports (list of list of str) – The list of lists of reports.

class ViolationFileHandler(target=<bound method Logger.warning of <Logger Loki (WARNING)>>, basedir=None, use_line_hashes=False)

  Bases: `GenericHandler`

  Report handler class that writes a YAML file with rules violated per file

  The content of the YAML file has the form

      'path/to/my/file.F90':
          filehash: 'abc123'
          rules:
          - SomeRule
          - SomeOtherRule

  This YAML file can be included into a linter config file to disable reporting of these rules on that version of the file (source modifications identified by `filehash`) in future runs.

  An alternative format of this file is the following

      'path/to/my/file.F90':
          rules:
          - Some Rule:
            - <line hash>
            - <line hash>
          - SomeOtherRule:
            - <line hash>

  This will disable reporting violations of given rules for the specified file, as long as the line hash matches one of the listed line hashes. This file format can be generated by specifying `use_line_hashes`.

  Parameters:

    - target – The output destination

    - basedir (str, optional) – Base directory path relative to which file paths are given.

    - use_line_hashes (bool, optional) – Disable rule violations per line

  handle(file_report)

    Create YAML block for this file

    Parameters:

      file_report (`FileReport`) – The file report to be processed

    Returns:

      YAML block for this file

    Return type:

      str

  output(handler_reports)

    Generate the YAML output from the list of reports.

class JunitXmlHandler(target=<bound method Logger.warning of <Logger Loki (WARNING)>>, basedir=None)

  Bases: `GenericHandler`

  Report handler class that generates JUnit-compatible XML output that can be understood by CI platforms such as Jenkins or Bamboo

  Parameters:

    - target – The output destination

    - basedir (str, optional) – Base directory path relative to which file paths are given.

  fmt_string = '{location} - {msg}'
  handle(file_report)

    Creates tuples of string arguments for junit_xml.TestCase

    Parameters:

      file_report (`FileReport`) – The file report to be processed

    Returns:

      Tuples of the form `(filename, [(kwargs, messages)])` with `kwargs` being the constructor arguments for junit_xml.TestCase and `messages` a list of strings.

    Return type:

      tuple(str, list)

  output(handler_reports)

    Generate the XML output from the list of reports.

class LazyTextfile(filename)

  Bases: `object`

  Helper class to encapsulate opening and writing to a file.

  This exists because opening the file immediately and then passing its `write` function to a `GenericHandler` makes it impossible to pickle it afterwards, which would make parallel execution infeasible.

  Instead of creating a more complicated interface for the handlers we opted for this way of a just-in-time/lazy file handler.

  The file is opened automatically for writing when calling `write()` for the first time, and closed when the object is garbage collected.

  Parameters:

    filename (str) – The filename of the output file

  write(msg)

    Write the given `msg` to the file

    The file is opened first, unless it is open already