Skip to content

Commit 92e336f

Browse files
Create a new reporter with all values
1 parent 31d449d commit 92e336f

File tree

2 files changed

+100
-21
lines changed

2 files changed

+100
-21
lines changed

pylint/reporters/json_reporter.py

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
from __future__ import annotations
88

99
import json
10-
from abc import abstractmethod
11-
from typing import TYPE_CHECKING, Optional
10+
from typing import TYPE_CHECKING, Any, Optional
1211

13-
from pylint.interfaces import UNDEFINED
12+
from pylint.interfaces import UNDEFINED, Confidence
1413
from pylint.message import Message
1514
from pylint.reporters.base_reporter import BaseReporter
1615
from pylint.typing import MessageLocationTuple
@@ -39,6 +38,10 @@
3938
},
4039
)
4140

41+
class JSONExport(OldJsonExport): # pylint: disable=inherit-non-class
42+
confidence: Confidence
43+
abspath: str
44+
4245

4346
class BaseJSONReporter(BaseReporter):
4447
"""Report messages and layouts in JSON."""
@@ -57,26 +60,24 @@ def display_reports(self, layout: Section) -> None:
5760
def _display(self, layout: Section) -> None:
5861
"""Do nothing."""
5962

60-
@abstractmethod
61-
def serialize(self, message: Message) -> OldJsonExport:
62-
...
63+
@staticmethod
64+
def serialize(message: Message) -> Any:
65+
raise NotImplementedError
6366

64-
@abstractmethod
65-
def deserialize(self, message_as_json: OldJsonExport) -> Message:
66-
...
67+
@staticmethod
68+
def deserialize(message_as_json: Any) -> Message:
69+
raise NotImplementedError
6770

6871

6972
class JSONReporter(BaseJSONReporter):
7073

7174
"""
7275
TODO: 3.0: Remove this JSONReporter in favor of the new one handling abs-path
7376
and confidence.
74-
75-
TODO: 2.15: Add a new JSONReporter handling abs-path, confidence and scores.
76-
(Ultimately all other breaking change related to json for 3.0).
7777
"""
7878

79-
def serialize(self, message: Message) -> OldJsonExport:
79+
@staticmethod
80+
def serialize(message: Message) -> OldJsonExport:
8081
return {
8182
"type": message.category,
8283
"module": message.module,
@@ -91,13 +92,13 @@ def serialize(self, message: Message) -> OldJsonExport:
9192
"message-id": message.msg_id,
9293
}
9394

94-
def deserialize(self, message_as_json: OldJsonExport) -> Message:
95+
@staticmethod
96+
def deserialize(message_as_json: OldJsonExport) -> Message:
9597
return Message(
9698
msg_id=message_as_json["message-id"],
9799
symbol=message_as_json["symbol"],
98100
msg=message_as_json["message"],
99101
location=MessageLocationTuple(
100-
# TODO: 3.0: Add abs-path and confidence in a new JSONReporter
101102
abspath=message_as_json["path"],
102103
path=message_as_json["path"],
103104
module=message_as_json["module"],
@@ -107,10 +108,56 @@ def deserialize(self, message_as_json: OldJsonExport) -> Message:
107108
end_line=message_as_json["endLine"],
108109
end_column=message_as_json["endColumn"],
109110
),
110-
# TODO: 3.0: Make confidence available in a new JSONReporter
111111
confidence=UNDEFINED,
112112
)
113113

114114

115+
class NewJSONReporter(BaseJSONReporter):
116+
117+
"""
118+
TODO: 3.0: Refactor this reporter so it's the only reporter.
119+
120+
TODO: 3.0: Handle all other breaking changes related to json for 3.0
121+
"""
122+
123+
@staticmethod
124+
def serialize(message: Message) -> JSONExport:
125+
return {
126+
"type": message.category,
127+
"module": message.module,
128+
"obj": message.obj,
129+
"line": message.line,
130+
"column": message.column,
131+
"endLine": message.end_line,
132+
"endColumn": message.end_column,
133+
"path": message.path,
134+
"symbol": message.symbol,
135+
"message": message.msg or "",
136+
"message-id": message.msg_id,
137+
"confidence": message.confidence,
138+
"abspath": message.abspath,
139+
}
140+
141+
@staticmethod
142+
def deserialize(message_as_json: JSONExport) -> Message:
143+
return Message(
144+
msg_id=message_as_json["message-id"],
145+
symbol=message_as_json["symbol"],
146+
msg=message_as_json["message"],
147+
location=MessageLocationTuple(
148+
abspath=message_as_json["abspath"],
149+
path=message_as_json["path"],
150+
module=message_as_json["module"],
151+
obj=message_as_json["obj"],
152+
line=message_as_json["line"],
153+
column=message_as_json["column"],
154+
end_line=message_as_json["endLine"],
155+
end_column=message_as_json["endColumn"],
156+
),
157+
confidence=message_as_json["confidence"],
158+
)
159+
160+
115161
def register(linter: PyLinter) -> None:
116162
linter.register_reporter(JSONReporter)
163+
linter.register_reporter(NewJSONReporter)

tests/reporters/unittest_json_reporter.py

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@
88

99
import json
1010
from io import StringIO
11+
from pathlib import Path
1112
from typing import Any
1213

1314
import pytest
1415

1516
from pylint import checkers
16-
from pylint.interfaces import UNDEFINED
17+
from pylint.interfaces import HIGH, UNDEFINED
1718
from pylint.lint import PyLinter
1819
from pylint.message import Message
1920
from pylint.reporters import JSONReporter
21+
from pylint.reporters.json_reporter import NewJSONReporter
2022
from pylint.reporters.ureports.nodes import EvaluationSection
2123
from pylint.typing import MessageLocationTuple
2224

@@ -131,7 +133,37 @@ def get_linter_result(score: bool, message: dict[str, Any]) -> list[dict[str, An
131133
)
132134
],
133135
)
134-
def test_serialize_deserialize(message):
135-
# TODO: 3.0: Add confidence handling, add path and abs path handling or a new JSONReporter
136-
json_message = JSONReporter.serialize(message)
137-
assert message == JSONReporter.deserialize(json_message)
136+
def test_serialize_deserialize(message: Message) -> None:
137+
for reporter in (JSONReporter, NewJSONReporter):
138+
json_message = reporter.serialize(message)
139+
assert message == reporter.deserialize(json_message)
140+
141+
142+
@pytest.mark.parametrize(
143+
"message",
144+
[
145+
pytest.param(
146+
Message(
147+
msg_id="C0111",
148+
symbol="missing-docstring",
149+
location=MessageLocationTuple(
150+
abspath=str(Path(__file__).resolve()),
151+
path=__file__,
152+
module="unittest_json_reporter",
153+
obj="obj",
154+
line=1,
155+
column=3,
156+
end_line=3,
157+
end_column=5,
158+
),
159+
msg="This is the actual message",
160+
confidence=HIGH,
161+
),
162+
id="everything-defined",
163+
)
164+
],
165+
)
166+
def test_serialize_deserialize_new_json(message: Message) -> None:
167+
json_message = NewJSONReporter.serialize(message)
168+
print(json_message)
169+
assert message == NewJSONReporter.deserialize(json_message)

0 commit comments

Comments
 (0)