Skip to content

Commit e63a5e8

Browse files
Fix exporting to JSON does not honor score option (3504)
This is a fix but I wonder... This looks like the fabled bug that will break countless integration by being fixed. `--score=y` is the default setting, and json is probably a prime candidate for automation. Is it reasonable to fix it and ask everyone to change their option to `-s n`? I'm pretty sure no one read the pylint's changelog unless we break their build.
1 parent 0eb6f93 commit e63a5e8

File tree

7 files changed

+66
-11
lines changed

7 files changed

+66
-11
lines changed

ChangeLog

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22
Pylint's ChangeLog
33
------------------
44

5+
What's New in Pylint 3.0.0?
6+
===========================
7+
8+
..
9+
Put breaking changes here and also in 'doc/whatsnew/3.0.rst'
10+
11+
* Fix the score option not being honored when exporting to JSON
12+
13+
The default setting was to have a score, but it did not work. Now it will give a score at the end of the json:
14+
15+
Close #3504
16+
17+
518
What's New in Pylint 2.10.0?
619
============================
720
Release date: TBA
@@ -11,7 +24,6 @@ Release date: TBA
1124

1225

1326
What's New in Pylint 2.9.1?
14-
===========================
1527
Release date: TBA
1628

1729
..

doc/whatsnew/3.0.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
**************************
2+
What's New in Pylint 3.0
3+
**************************
4+
5+
:Release: 3.0
6+
:Date: TBA
7+
8+
9+
Summary -- Release highlights
10+
=============================
11+
12+
13+
New checkers
14+
============
15+
16+
17+
Other Changes
18+
=============
19+
20+
* The score option for JSON export has been fixed
21+
22+
The default setting is to have a score, but it did not work before.
23+
If a score appeared in your json, and you want to go back what you
24+
had before, you must change the score option to "--score=n"

doc/whatsnew/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ High level descriptions of the most important changes between major Pylint versi
99
.. toctree::
1010
:maxdepth: 1
1111

12+
3.0.rst
1213
2.9.rst
1314
2.8.rst
1415
2.7.rst

pylint/lint/pylinter.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,13 +1231,9 @@ def open(self):
12311231
self.stats[msg_cat] = 0
12321232

12331233
def generate_reports(self):
1234-
"""close the whole package /module, it's time to make reports !
1235-
1236-
if persistent run, pickle results for later comparison
1237-
"""
1238-
# Display whatever messages are left on the reporter.
1239-
self.reporter.display_messages(report_nodes.Section())
1234+
"""Close the whole package /module, it's time to make reports !
12401235
1236+
if persistent run, pickle results for later comparison."""
12411237
if self.file_state.base_name is not None:
12421238
# load previous results if any
12431239
previous_stats = config.load_results(self.file_state.base_name)
@@ -1256,6 +1252,8 @@ def generate_reports(self):
12561252
else:
12571253
self.reporter.on_close(self.stats, {})
12581254
score_value = None
1255+
# Display whatever messages are left on the reporter.
1256+
self.reporter.display_messages(report_nodes.Section())
12591257
return score_value
12601258

12611259
def _report_evaluation(self):

pylint/reporters/json_reporter.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
# For details: https://github.com/PyCQA/pylint/blob/master/LICENSE
1212

1313
"""JSON reporter"""
14+
import io
1415
import json
1516

1617
from pylint.interfaces import IReporter
1718
from pylint.reporters.base_reporter import BaseReporter
19+
from pylint.reporters.ureports.text_writer import TextWriter
1820

1921

2022
class JSONReporter(BaseReporter):
@@ -43,7 +45,11 @@ def display_messages(self, layout):
4345
print(json.dumps(json_dumpable, indent=4), file=self.out)
4446

4547
def display_reports(self, layout):
46-
"""Don't do anything in this reporter."""
48+
output = io.StringIO()
49+
TextWriter().format(layout, output)
50+
score = output.getvalue().split("Your")[1]
51+
score = score.split(r"/10")[0]
52+
self.messages.append({"score": f"Your{score}/10"})
4753

4854
def _display(self, layout):
4955
"""Do nothing."""

tests/test_self.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ def test_json_report_does_not_escape_quotes(self):
434434
self._runtest([module], code=4, reporter=JSONReporter(out))
435435
output = json.loads(out.getvalue())
436436
assert isinstance(output, list)
437-
assert len(output) == 1
437+
assert len(output) == 2
438438
assert isinstance(output[0], dict)
439439
expected = {
440440
"symbol": "unused-variable",
@@ -445,10 +445,13 @@ def test_json_report_does_not_escape_quotes(self):
445445
"line": 4,
446446
"type": "warning",
447447
}
448+
448449
message = output[0]
449450
for key, value in expected.items():
450451
assert key in message
451452
assert message[key] == value
453+
expected = {"score": "Your code has been rated at 7.50/10"}
454+
assert output[-1] == expected
452455

453456
def test_information_category_disabled_by_default(self):
454457
expected = "Your code has been rated at 10.00/10"

tests/unittest_reporters_json.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from pylint.reporters import JSONReporter
2222
from pylint.reporters.ureports.nodes import EvaluationSection
2323

24-
expected_score_message = "Expected score message"
24+
expected_score_message = "Your code has been rated at 7.50/10"
2525
expected_result = [
2626
[
2727
("column", 0),
@@ -37,6 +37,14 @@
3737
]
3838

3939

40+
def test_simple_json_output_with_score():
41+
report = get_linter_result(score=True)
42+
assert len(report) == 2
43+
report_result = [sorted(report[0].items(), key=lambda item: item[0])]
44+
assert report_result == expected_result
45+
assert report[1] == {"score": expected_score_message}
46+
47+
4048
def test_simple_json_output_no_score():
4149
report = get_linter_result(score=False)
4250
assert len(report) == 1
@@ -56,7 +64,10 @@ def get_linter_result(score):
5664
linter.add_message("line-too-long", line=1, args=(1, 2))
5765
# we call those methods because we didn't actually run the checkers
5866
if score:
59-
reporter.display_reports(EvaluationSection(expected_score_message))
67+
generated_msg = "-------------------------------------\r\n{}\r\n".format(
68+
expected_score_message
69+
)
70+
reporter.display_reports(EvaluationSection(generated_msg))
6071
reporter.display_messages(None)
6172
report_result = json.loads(output.getvalue())
6273
return report_result

0 commit comments

Comments
 (0)