Coverage for C:\Repos\ekr-pylint\pylint\reporters\multi_reporter.py: 49%
59 statements
« prev ^ index » next coverage.py v6.4, created at 2022-05-24 10:21 -0500
« prev ^ index » next coverage.py v6.4, created at 2022-05-24 10:21 -0500
1# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
2# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
3# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt
5from __future__ import annotations
7import os
8from collections.abc import Callable
9from typing import TYPE_CHECKING, TextIO
11from pylint.message import Message
12from pylint.reporters.base_reporter import BaseReporter
13from pylint.utils import LinterStats
15if TYPE_CHECKING:
16 from pylint.lint import PyLinter
17 from pylint.reporters.ureports.nodes import Section
20class MultiReporter:
21 """Reports messages and layouts in plain text."""
23 name = "_internal_multi_reporter"
24 # Note: do not register this reporter with linter.register_reporter as it is
25 # not intended to be used directly like a regular reporter, but is
26 # instead used to implement the
27 # `--output-format=json:somefile.json,colorized`
28 # multiple output formats feature
30 extension = ""
32 def __init__(
33 self,
34 sub_reporters: list[BaseReporter],
35 close_output_files: Callable[[], None],
36 output: TextIO | None = None,
37 ):
38 self._sub_reporters = sub_reporters
39 self.close_output_files = close_output_files
40 self._path_strip_prefix = os.getcwd() + os.sep
41 self._linter: PyLinter | None = None
42 self.out = output
43 self.messages: list[Message] = []
45 @property
46 def out(self) -> TextIO | None:
47 return self.__out
49 @out.setter
50 def out(self, output: TextIO | None = None) -> None:
51 """MultiReporter doesn't have its own output.
53 This method is only provided for API parity with BaseReporter
54 and should not be called with non-None values for 'output'.
55 """
56 self.__out = None
57 if output is not None:
58 raise NotImplementedError("MultiReporter does not support direct output.")
60 def __del__(self) -> None:
61 self.close_output_files()
63 @property
64 def path_strip_prefix(self) -> str:
65 return self._path_strip_prefix
67 @property
68 def linter(self) -> PyLinter | None:
69 return self._linter
71 @linter.setter
72 def linter(self, value: PyLinter) -> None:
73 self._linter = value
74 for rep in self._sub_reporters:
75 rep.linter = value
77 def handle_message(self, msg: Message) -> None:
78 """Handle a new message triggered on the current file."""
79 for rep in self._sub_reporters:
80 rep.handle_message(msg)
82 def writeln(self, string: str = "") -> None:
83 """Write a line in the output buffer."""
84 for rep in self._sub_reporters:
85 rep.writeln(string)
87 def display_reports(self, layout: Section) -> None:
88 """Display results encapsulated in the layout tree."""
89 for rep in self._sub_reporters:
90 rep.display_reports(layout)
92 def display_messages(self, layout: Section | None) -> None:
93 """Hook for displaying the messages of the reporter."""
94 for rep in self._sub_reporters:
95 rep.display_messages(layout)
97 def on_set_current_module(self, module: str, filepath: str | None) -> None:
98 """Hook called when a module starts to be analysed."""
99 for rep in self._sub_reporters:
100 rep.on_set_current_module(module, filepath)
102 def on_close(
103 self,
104 stats: LinterStats,
105 previous_stats: LinterStats | None,
106 ) -> None:
107 """Hook called when a module finished analyzing."""
108 for rep in self._sub_reporters:
109 rep.on_close(stats, previous_stats)