Add typing for ``json_reporter`` and sub-classes
diff --git a/pylint/interfaces.py b/pylint/interfaces.py index 8480f9d..e657e71 100644 --- a/pylint/interfaces.py +++ b/pylint/interfaces.py
@@ -18,10 +18,13 @@ """Interfaces for Pylint objects""" from collections import namedtuple -from typing import Tuple +from typing import TYPE_CHECKING, Tuple from astroid import nodes +if TYPE_CHECKING: + from pylint.reporters.ureports.nodes import Section + Confidence = namedtuple("Confidence", ["name", "description"]) # Warning Certainties HIGH = Confidence("HIGH", "No false positive possible.") @@ -99,7 +102,7 @@ def handle_message(self, msg) -> None: """Handle the given message object.""" - def display_reports(self, layout): + def display_reports(self, layout: "Section") -> None: """display results encapsulated in the layout tree"""
diff --git a/pylint/reporters/base_reporter.py b/pylint/reporters/base_reporter.py index e74ffdd..9bd9e80 100644 --- a/pylint/reporters/base_reporter.py +++ b/pylint/reporters/base_reporter.py
@@ -3,11 +3,15 @@ import os import sys -from typing import List, Optional +from typing import TYPE_CHECKING, List, Optional from pylint.message import Message +from pylint.reporters.ureports.nodes import Text from pylint.typing import CheckerStats +if TYPE_CHECKING: + from pylint.reporters.ureports.nodes import Section + class BaseReporter: """base class for reporters @@ -39,18 +43,21 @@ """write a line in the output buffer""" print(string, file=self.out) - def display_reports(self, layout): + def display_reports(self, layout: "Section") -> None: """display results encapsulated in the layout tree""" self.section = 0 if layout.report_id: - layout.children[0].children[0].data += f" ({layout.report_id})" + if isinstance(layout.children[0].children[0], Text): + layout.children[0].children[0].data += f" ({layout.report_id})" + else: + raise ValueError(f"Incorrect child for {layout.children[0].children}") self._display(layout) - def _display(self, layout): + def _display(self, layout: "Section") -> None: """display the layout""" raise NotImplementedError() - def display_messages(self, layout): + def display_messages(self, layout: Optional["Section"]) -> None: """Hook for displaying the messages of the reporter This will be called whenever the underlying messages
diff --git a/pylint/reporters/collecting_reporter.py b/pylint/reporters/collecting_reporter.py index 145c3c8..fbd9eb4 100644 --- a/pylint/reporters/collecting_reporter.py +++ b/pylint/reporters/collecting_reporter.py
@@ -1,7 +1,12 @@ # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html # For details: https://github.com/PyCQA/pylint/blob/main/LICENSE +from typing import TYPE_CHECKING + from pylint.reporters.base_reporter import BaseReporter +if TYPE_CHECKING: + from pylint.reporters.ureports.nodes import Section + class CollectingReporter(BaseReporter): """collects messages""" @@ -15,4 +20,5 @@ def reset(self) -> None: self.messages = [] - _display = None + def _display(self, layout: "Section") -> None: + pass
diff --git a/pylint/reporters/json_reporter.py b/pylint/reporters/json_reporter.py index 12aab69..87949c1 100644 --- a/pylint/reporters/json_reporter.py +++ b/pylint/reporters/json_reporter.py
@@ -13,10 +13,15 @@ """JSON reporter""" import json +from typing import TYPE_CHECKING, Optional from pylint.interfaces import IReporter from pylint.reporters.base_reporter import BaseReporter +if TYPE_CHECKING: + from pylint.lint.pylinter import PyLinter + from pylint.reporters.ureports.nodes import Section + class JSONReporter(BaseReporter): """Report messages and layouts in JSON.""" @@ -25,7 +30,7 @@ name = "json" extension = "json" - def display_messages(self, layout): + def display_messages(self, layout: Optional["Section"]) -> None: """Launch layouts display""" json_dumpable = [ { @@ -43,13 +48,13 @@ ] print(json.dumps(json_dumpable, indent=4), file=self.out) - def display_reports(self, layout): + def display_reports(self, layout: "Section") -> None: """Don't do anything in this reporter.""" - def _display(self, layout): + def _display(self, layout: "Section") -> None: """Do nothing.""" -def register(linter): +def register(linter: "PyLinter") -> None: """Register the reporter classes with the linter.""" linter.register_reporter(JSONReporter)
diff --git a/pylint/reporters/multi_reporter.py b/pylint/reporters/multi_reporter.py index 445e9b3..b3b67d8 100644 --- a/pylint/reporters/multi_reporter.py +++ b/pylint/reporters/multi_reporter.py
@@ -3,14 +3,16 @@ import os -from typing import IO, Any, AnyStr, Callable, List, Optional +from typing import IO, TYPE_CHECKING, Any, AnyStr, Callable, List, Optional from pylint.interfaces import IReporter from pylint.message import Message from pylint.reporters.base_reporter import BaseReporter -from pylint.reporters.ureports.nodes import BaseLayout from pylint.typing import CheckerStats +if TYPE_CHECKING: + from pylint.reporters.ureports.nodes import Section + AnyFile = IO[AnyStr] PyLinter = Any @@ -78,12 +80,12 @@ for rep in self._sub_reporters: rep.writeln(string) - def display_reports(self, layout: BaseLayout) -> None: + def display_reports(self, layout: "Section") -> None: """display results encapsulated in the layout tree""" for rep in self._sub_reporters: rep.display_reports(layout) - def display_messages(self, layout: BaseLayout) -> None: + def display_messages(self, layout: Optional["Section"]) -> None: """hook for displaying the messages of the reporter""" for rep in self._sub_reporters: rep.display_messages(layout)
diff --git a/pylint/reporters/text.py b/pylint/reporters/text.py index 53eef21..e941ba6 100644 --- a/pylint/reporters/text.py +++ b/pylint/reporters/text.py
@@ -26,7 +26,7 @@ import os import sys import warnings -from typing import Optional +from typing import TYPE_CHECKING, Optional from pylint import utils from pylint.interfaces import IReporter @@ -34,6 +34,9 @@ from pylint.reporters import BaseReporter from pylint.reporters.ureports.text_writer import TextWriter +if TYPE_CHECKING: + from pylint.reporters.ureports.nodes import Section + TITLE_UNDERLINES = ["", "=", "-", "."] ANSI_PREFIX = "\033[" @@ -155,7 +158,7 @@ self.writeln("************* ") self.write_message(msg) - def _display(self, layout): + def _display(self, layout: "Section") -> None: """launch layouts display""" print(file=self.out) TextWriter().format(layout, self.out)
diff --git a/pylint/testutils/reporter_for_tests.py b/pylint/testutils/reporter_for_tests.py index 9527544..480f1ed 100644 --- a/pylint/testutils/reporter_for_tests.py +++ b/pylint/testutils/reporter_for_tests.py
@@ -3,12 +3,15 @@ from io import StringIO from os import getcwd, linesep, sep -from typing import Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional from pylint import interfaces from pylint.message import Message from pylint.reporters import BaseReporter +if TYPE_CHECKING: + from pylint.reporters.ureports.nodes import Section + class GenericTestReporter(BaseReporter): """reporter storing plain text messages""" @@ -56,25 +59,27 @@ # pylint: enable=unused-argument - def display_reports(self, layout): + def display_reports(self, layout: "Section") -> None: """ignore layouts""" - _display = None + def _display(self, layout: "Section") -> None: + pass class MinimalTestReporter(BaseReporter): def on_set_current_module(self, module: str, filepath: Optional[str]) -> None: self.messages = [] - _display = None + def _display(self, layout: "Section") -> None: + pass class FunctionalTestReporter(BaseReporter): def on_set_current_module(self, module: str, filepath: Optional[str]) -> None: self.messages = [] - def display_reports(self, layout): + def display_reports(self, layout: "Section") -> None: """Ignore layouts and don't call self._display().""" - def _display(self, layout): + def _display(self, layout: "Section") -> None: pass
diff --git a/tests/extensions/test_broad_try_clause.py b/tests/extensions/test_broad_try_clause.py index 85c51eb..4e38adb 100644 --- a/tests/extensions/test_broad_try_clause.py +++ b/tests/extensions/test_broad_try_clause.py
@@ -14,19 +14,22 @@ """Tests for the pylint checker in :mod:`pylint.extensions.broad_try_clause`""" import unittest from os import path as osp -from typing import Optional +from typing import TYPE_CHECKING, Optional from pylint import checkers from pylint.extensions.broad_try_clause import BroadTryClauseChecker from pylint.lint import PyLinter from pylint.reporters import BaseReporter +if TYPE_CHECKING: + from pylint.reporters.ureports.nodes import Section + class BroadTryClauseTestReporter(BaseReporter): def on_set_current_module(self, module: str, filepath: Optional[str]) -> None: self.messages = [] - def _display(self, layout): + def _display(self, layout: "Section") -> None: pass
diff --git a/tests/extensions/test_comparetozero.py b/tests/extensions/test_comparetozero.py index 52be28c..7b5bb16 100644 --- a/tests/extensions/test_comparetozero.py +++ b/tests/extensions/test_comparetozero.py
@@ -15,19 +15,22 @@ import os import unittest -from typing import Optional +from typing import TYPE_CHECKING, Optional from pylint import checkers from pylint.extensions.comparetozero import CompareToZeroChecker from pylint.lint import PyLinter from pylint.reporters import BaseReporter +if TYPE_CHECKING: + from pylint.reporters.ureports.nodes import Section + class CompareToZeroTestReporter(BaseReporter): def on_set_current_module(self, module: str, filepath: Optional[str]) -> None: self.messages = [] - def _display(self, layout): + def _display(self, layout: "Section") -> None: pass
diff --git a/tests/test_self.py b/tests/test_self.py index 9c04441..41e7898 100644 --- a/tests/test_self.py +++ b/tests/test_self.py
@@ -51,7 +51,7 @@ from io import StringIO from os.path import abspath, dirname, join from pathlib import Path -from typing import Any, Generator, Iterator, List, Optional, Union +from typing import TYPE_CHECKING, Any, Generator, Iterator, List, Optional, Union from unittest import mock from unittest.mock import patch @@ -66,9 +66,11 @@ from pylint.message import Message from pylint.reporters import JSONReporter from pylint.reporters.text import BaseReporter, ColorizedTextReporter, TextReporter -from pylint.reporters.ureports.nodes import EvaluationSection from pylint.utils import utils +if TYPE_CHECKING: + from pylint.reporters.ureports.nodes import Section + HERE = abspath(dirname(__file__)) CLEAN_PATH = re.escape(dirname(dirname(__file__)) + os.path.sep) UNNECESSARY_LAMBDA = join( @@ -116,7 +118,7 @@ for rep in self._reporters: rep.handle_message(msg) - def _display(self, layout: EvaluationSection) -> None: + def _display(self, layout: "Section") -> None: pass @property
diff --git a/tests/unittest_reporting.py b/tests/unittest_reporting.py index 88f9c43..c0fdb61 100644 --- a/tests/unittest_reporting.py +++ b/tests/unittest_reporting.py
@@ -21,6 +21,7 @@ from contextlib import redirect_stdout from io import StringIO from json import dumps +from typing import TYPE_CHECKING import pytest @@ -31,6 +32,9 @@ from pylint.reporters.text import ParseableTextReporter, TextReporter from pylint.typing import FileItem +if TYPE_CHECKING: + from pylint.reporters.ureports.nodes import Section + @pytest.fixture(scope="module") def reporter(): @@ -93,7 +97,7 @@ def writeln(self, string=""): pass - def _display(self, layout): + def _display(self, layout: "Section") -> None: pass @@ -257,7 +261,7 @@ def test_display_results_is_renamed(): class CustomReporter(TextReporter): - def _display(self, layout): + def _display(self, layout: "Section") -> None: return None reporter = CustomReporter()