Skip to content

Commit b784f4f

Browse files
[JsonReporter] Add serialization functions to JsonReporter
1 parent f3d7ce9 commit b784f4f

File tree

3 files changed

+80
-17
lines changed

3 files changed

+80
-17
lines changed

doc/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
# If extensions (or modules to document with autodoc) are in another directory,
2727
# add these directories to sys.path here. If the directory is relative to the
28-
# documentation root, use os.path.abspath to make it absolute, like shown here.
28+
# documentation root, use 'os.path.abspath' to make it absolute, like shown here.
2929
sys.path.append(os.path.abspath("exts"))
3030

3131
# -- General configuration -----------------------------------------------------

pylint/reporters/json_reporter.py

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
import json
1010
from typing import TYPE_CHECKING
1111

12+
from pylint.interfaces import UNDEFINED
13+
from pylint.message import Message
1214
from pylint.reporters.base_reporter import BaseReporter
15+
from pylint.typing import MessageLocationTuple
1316

1417
if TYPE_CHECKING:
1518
from pylint.lint.pylinter import PyLinter
@@ -24,24 +27,47 @@ class JSONReporter(BaseReporter):
2427

2528
def display_messages(self, layout: Section | None) -> None:
2629
"""Launch layouts display."""
27-
json_dumpable = [
28-
{
29-
"type": msg.category,
30-
"module": msg.module,
31-
"obj": msg.obj,
32-
"line": msg.line,
33-
"column": msg.column,
34-
"endLine": msg.end_line,
35-
"endColumn": msg.end_column,
36-
"path": msg.path,
37-
"symbol": msg.symbol,
38-
"message": msg.msg or "",
39-
"message-id": msg.msg_id,
40-
}
41-
for msg in self.messages
42-
]
30+
json_dumpable = [self.serialize(message) for message in self.messages]
4331
print(json.dumps(json_dumpable, indent=4), file=self.out)
4432

33+
@staticmethod
34+
def serialize(message: Message) -> dict[str, int | str | None]:
35+
# TODO (3.0) add abs-path and confidence
36+
return {
37+
"type": message.category,
38+
"module": message.module,
39+
"obj": message.obj,
40+
"line": message.line,
41+
"column": message.column,
42+
"endLine": message.end_line,
43+
"endColumn": message.end_column,
44+
"path": message.path,
45+
"symbol": message.symbol,
46+
"message": message.msg or "",
47+
"message-id": message.msg_id,
48+
}
49+
50+
@staticmethod
51+
def deserialize(message_as_json: dict) -> Message:
52+
return Message(
53+
msg_id=message_as_json["message-id"],
54+
symbol=message_as_json["symbol"],
55+
msg=message_as_json["message"],
56+
location=MessageLocationTuple(
57+
# TODO (3.0) abs-path is not available in json export
58+
abspath=message_as_json["path"],
59+
path=message_as_json["path"],
60+
module=message_as_json["module"],
61+
obj=message_as_json["obj"],
62+
line=message_as_json["line"],
63+
column=message_as_json["column"],
64+
end_line=message_as_json["endLine"],
65+
end_column=message_as_json["endColumn"],
66+
),
67+
# TODO (3.0) confidence is not available in json export
68+
confidence=UNDEFINED,
69+
)
70+
4571
def display_reports(self, layout: Section) -> None:
4672
"""Don't do anything in this reporter."""
4773

tests/reporters/unittest_json_reporter.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@
1010
from io import StringIO
1111
from typing import Any
1212

13+
import pytest
14+
1315
from pylint import checkers
16+
from pylint.interfaces import UNDEFINED
1417
from pylint.lint import PyLinter
18+
from pylint.message import Message
1519
from pylint.reporters import JSONReporter
1620
from pylint.reporters.ureports.nodes import EvaluationSection
21+
from pylint.typing import MessageLocationTuple
1722

1823
expected_score_message = "Expected score message"
1924

@@ -98,3 +103,35 @@ def get_linter_result(score: bool, message: dict[str, Any]) -> list[dict[str, An
98103
reporter.display_messages(None)
99104
report_result = json.loads(output.getvalue())
100105
return report_result
106+
107+
108+
@pytest.mark.parametrize(
109+
"message",
110+
[
111+
pytest.param(
112+
Message(
113+
msg_id="C0111",
114+
symbol="missing-docstring",
115+
location=MessageLocationTuple(
116+
# abs-path and path must be equal because one of them is removed
117+
# in the JsonReporter
118+
abspath=__file__,
119+
path=__file__,
120+
module="unittest_json_reporter",
121+
obj="obj",
122+
line=1,
123+
column=3,
124+
end_line=3,
125+
end_column=5,
126+
),
127+
msg="This is the actual message",
128+
confidence=UNDEFINED,
129+
),
130+
id="everything-defined",
131+
)
132+
],
133+
)
134+
def test_serialize_deserialize(message):
135+
# TODO (3.0): Add confidence handling, add path and abs path handling
136+
json_message = JSONReporter.serialize(message)
137+
assert message == JSONReporter.deserialize(json_message)

0 commit comments

Comments
 (0)