Skip to content

Commit bd65461

Browse files
amamlaDanielNoord
authored andcommitted
Fixing inconsistent hashing issue in BaseChecker causing some reports not being exported.
If any of checker's message definition tuples provided extra message option (optional) `BaseChecker.create_message_definition_from_tuple()` method was overriding those options by adding default `scope` parameter to them. This resulted in message instances having incosistent hashes during their lifecycle and could not be found in reports dictionary when `ReportsHandlerMixIn.make_reports()` was called.
1 parent fb2faee commit bd65461

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

doc/whatsnew/fragments/9001.bugfix

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixing inconsistent hashing issue in `BaseChecker` causing some reports not being exported.
2+
3+
Closes #9001

pylint/checkers/base_checker.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ def create_message_definition_from_tuple(
190190
default_scope = WarningScope.NODE
191191
options: ExtraMessageOptions = {}
192192
if len(msg_tuple) == 4:
193-
(msg, symbol, descr, options) = msg_tuple # type: ignore[misc]
193+
(msg, symbol, descr, msg_options) = msg_tuple # type: ignore[misc]
194+
options = ExtraMessageOptions(**msg_options)
194195
elif len(msg_tuple) == 3:
195196
(msg, symbol, descr) = msg_tuple # type: ignore[misc]
196197
else:

tests/checkers/unittest_base_checker.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ def __init__(self) -> None:
6262
}
6363

6464

65+
class MessageWithOptionsChecker(BaseChecker):
66+
name = "message-with-options-checker"
67+
msgs = {
68+
"W0003": (
69+
"Just a message with pre-defined options %s()",
70+
"message-with-options",
71+
"Message with options dict to test consistent hashing.",
72+
{"old_names": [("W1003", "old-message-with-options")], "shared": True},
73+
),
74+
}
75+
76+
6577
def test_base_checker_doc() -> None:
6678
basic = OtherBasicChecker()
6779
expected_beginning = """\
@@ -156,3 +168,18 @@ def test_base_checker_invalid_message() -> None:
156168
linter = PyLinter()
157169
with pytest.raises(InvalidMessageError):
158170
linter.register_checker(MissingFieldsChecker(linter))
171+
172+
173+
def test_base_checker_consistent_hash() -> None:
174+
linter = PyLinter()
175+
checker = MessageWithOptionsChecker(linter)
176+
some_set = {checker}
177+
178+
original_hash = hash(checker)
179+
assert checker in some_set
180+
181+
for msgid, msg in checker.msgs.items():
182+
checker.create_message_definition_from_tuple(msgid, msg)
183+
184+
assert hash(checker) == original_hash
185+
assert checker in some_set

0 commit comments

Comments
 (0)