Skip to content

Commit d6fa341

Browse files
Mark no-self-use as moved to extensions (#6932)
* Mark `no-self-use` as deleted (moved to extensions) * Separate notions of deleted messages from moved messages Co-authored-by: Pierre Sassoulas <[email protected]>
1 parent af3816b commit d6fa341

File tree

7 files changed

+89
-12
lines changed

7 files changed

+89
-12
lines changed

pylint/config/callback_actions.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,10 @@ def _call(
378378
for msgid in utils._check_csv(values[0]):
379379
try:
380380
xabling_function(msgid)
381-
except exceptions.DeletedMessageError as e:
381+
except (
382+
exceptions.DeletedMessageError,
383+
exceptions.MessageBecameExtensionError,
384+
) as e:
382385
self.linter._stashed_messages[
383386
(self.linter.current_name, "useless-option-value")
384387
].append((option_string, str(e)))

pylint/exceptions.py

+11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ def __init__(self, msgid_or_symbol: str, removal_explanation: str):
2424
)
2525

2626

27+
class MessageBecameExtensionError(UnknownMessageError):
28+
"""Raised when a message id or symbol that was moved to an optional
29+
extension is encountered.
30+
"""
31+
32+
def __init__(self, msgid_or_symbol: str, moved_explanation: str):
33+
super().__init__(
34+
f"'{msgid_or_symbol}' was moved to an optional extension, see {moved_explanation}."
35+
)
36+
37+
2738
class EmptyReportError(Exception):
2839
"""Raised when a report is empty and so should not be displayed."""
2940

pylint/lint/message_state_handler.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,10 @@ def process_tokens(self, tokens: list[tokenize.TokenInfo]) -> None:
410410
l_start -= 1
411411
try:
412412
meth(msgid, "module", l_start)
413-
except exceptions.DeletedMessageError as e:
413+
except (
414+
exceptions.DeletedMessageError,
415+
exceptions.MessageBecameExtensionError,
416+
) as e:
414417
self.linter.add_message(
415418
"useless-option-value",
416419
args=(pragma_repr.action, e),

pylint/message/_deleted_message_ids.py

+29
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ class DeletedMessage(NamedTuple):
124124
DeletedMessage("W0111", "assign-to-new-keyword"),
125125
],
126126
}
127+
MOVED_TO_EXTENSIONS = {
128+
"https://pylint.pycqa.org/en/latest/whatsnew/2/2.14/summary.html#removed-checkers": [
129+
DeletedMessage("R0201", "no-self-use")
130+
],
131+
}
127132

128133

129134
@lru_cache(maxsize=None)
@@ -148,3 +153,27 @@ def is_deleted_msgid(msgid: str) -> str | None:
148153
):
149154
return explanation
150155
return None
156+
157+
158+
@lru_cache(maxsize=None)
159+
def is_moved_symbol(symbol: str) -> str | None:
160+
"""Return the explanation for moving if the message was moved to extensions."""
161+
for explanation, moved_messages in MOVED_TO_EXTENSIONS.items():
162+
for moved_message in moved_messages:
163+
if symbol == moved_message.symbol or any(
164+
symbol == m[1] for m in moved_message.old_names
165+
):
166+
return explanation
167+
return None
168+
169+
170+
@lru_cache(maxsize=None)
171+
def is_moved_msgid(msgid: str) -> str | None:
172+
"""Return the explanation for moving if the message was moved to extensions."""
173+
for explanation, moved_messages in MOVED_TO_EXTENSIONS.items():
174+
for moved_message in moved_messages:
175+
if msgid == moved_message.msgid or any(
176+
msgid == m[0] for m in moved_message.old_names
177+
):
178+
return explanation
179+
return None

pylint/message/message_id_store.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@
99
from pylint.exceptions import (
1010
DeletedMessageError,
1111
InvalidMessageError,
12+
MessageBecameExtensionError,
1213
UnknownMessageError,
1314
)
14-
from pylint.message._deleted_message_ids import is_deleted_msgid, is_deleted_symbol
15+
from pylint.message._deleted_message_ids import (
16+
is_deleted_msgid,
17+
is_deleted_symbol,
18+
is_moved_msgid,
19+
is_moved_symbol,
20+
)
1521

1622

1723
class MessageIdStore:
@@ -128,20 +134,27 @@ def get_active_msgids(self, msgid_or_symbol: str) -> list[str]:
128134
# If we don't have a cached value yet we compute it
129135
msgid: str | None
130136
deletion_reason = None
137+
moved_reason = None
131138
if msgid_or_symbol[1:].isdigit():
132139
# Only msgid can have a digit as second letter
133140
msgid = msgid_or_symbol.upper()
134141
symbol = self.__msgid_to_symbol.get(msgid)
135142
if not symbol:
136143
deletion_reason = is_deleted_msgid(msgid)
144+
if deletion_reason is None:
145+
moved_reason = is_moved_msgid(msgid)
137146
else:
138147
symbol = msgid_or_symbol
139148
msgid = self.__symbol_to_msgid.get(msgid_or_symbol)
140149
if not msgid:
141150
deletion_reason = is_deleted_symbol(symbol)
151+
if deletion_reason is None:
152+
moved_reason = is_moved_symbol(symbol)
142153
if not msgid or not symbol:
143154
if deletion_reason is not None:
144155
raise DeletedMessageError(msgid_or_symbol, deletion_reason)
156+
if moved_reason is not None:
157+
raise MessageBecameExtensionError(msgid_or_symbol, moved_reason)
145158
error_msg = f"No such message id or symbol '{msgid_or_symbol}'."
146159
raise UnknownMessageError(error_msg)
147160
ids = self.__old_names.get(msgid, [msgid])

tests/functional/b/bad_option_value.py

+12
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,33 @@
44
# pylint: disable=C05048 # [unknown-option-value]
55
# Standard disable with deleted symbol
66
# pylint: disable=execfile-builtin # [useless-option-value]
7+
# Standard disable with symbol moved to extension
8+
# pylint: disable=no-self-use # [useless-option-value]
79
# Standard disable with deleted msgid
810
# pylint: disable=W1656 # [useless-option-value]
11+
# Standard disable with msgid moved to extension
12+
# pylint: disable=R0201 # [useless-option-value]
913
# disable-next with unknown value
1014
# pylint: disable-next=R78948 # [unknown-option-value]
1115
# disable-next with deleted symbol
1216
# pylint: disable-next=deprecated-types-field # [useless-option-value]
1317
# disable-next with deleted msgid
1418
# pylint: disable-next=W1634 # [useless-option-value]
19+
# disable-next with symbol moved to extension
20+
# pylint: disable-next=no-self-use # [useless-option-value]
21+
# disable-next with msgid moved to extension
22+
# pylint: disable-next=R0201 # [useless-option-value]
1523

1624
# enable with unknown value
1725
# pylint:enable=W04044 # [unknown-option-value]
1826
# enable with deleted symbol
1927
# pylint:enable=dict-values-not-iterating # [useless-option-value]
28+
# enable with symbol moved to extension
29+
# pylint: enable=no-self-use # [useless-option-value]
2030
# enable with deleted msgid
2131
# pylint:enable=W1622 # [useless-option-value]
32+
# enable with msgid moved to extension
33+
# pylint: enable=R0201 # [useless-option-value]
2234

2335
# Standard disable with deleted old name symbol of deleted message
2436
# pylint: disable=no-space-after-operator # [useless-option-value]
+15-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
unknown-option-value:4:0:None:None::Unknown option value for 'disable', expected a valid pylint message and got 'C05048':HIGH
22
useless-option-value:6:0:None:None::"Useless option value for 'disable', 'execfile-builtin' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
3-
useless-option-value:8:0:None:None::"Useless option value for 'disable', 'W1656' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
4-
unknown-option-value:10:0:None:None::Unknown option value for 'disable-next', expected a valid pylint message and got 'R78948':HIGH
5-
useless-option-value:12:0:None:None::"Useless option value for 'disable-next', 'deprecated-types-field' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
6-
useless-option-value:14:0:None:None::"Useless option value for 'disable-next', 'W1634' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
7-
unknown-option-value:17:0:None:None::Unknown option value for 'enable', expected a valid pylint message and got 'W04044':HIGH
8-
useless-option-value:19:0:None:None::"Useless option value for 'enable', 'dict-values-not-iterating' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
9-
useless-option-value:21:0:None:None::"Useless option value for 'enable', 'W1622' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
10-
useless-option-value:24:0:None:None::"Useless option value for 'disable', 'no-space-after-operator' was removed from pylint, see https://github.com/PyCQA/pylint/pull/3577.":HIGH
11-
useless-option-value:26:0:None:None::"Useless option value for 'disable', 'C0323' was removed from pylint, see https://github.com/PyCQA/pylint/pull/3577.":HIGH
3+
useless-option-value:8:0:None:None::"Useless option value for 'disable', 'no-self-use' was moved to an optional extension, see https://pylint.pycqa.org/en/latest/whatsnew/2/2.14/summary.html#removed-checkers.":HIGH
4+
useless-option-value:10:0:None:None::"Useless option value for 'disable', 'W1656' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
5+
useless-option-value:12:0:None:None::"Useless option value for 'disable', 'R0201' was moved to an optional extension, see https://pylint.pycqa.org/en/latest/whatsnew/2/2.14/summary.html#removed-checkers.":HIGH
6+
unknown-option-value:14:0:None:None::Unknown option value for 'disable-next', expected a valid pylint message and got 'R78948':HIGH
7+
useless-option-value:16:0:None:None::"Useless option value for 'disable-next', 'deprecated-types-field' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
8+
useless-option-value:18:0:None:None::"Useless option value for 'disable-next', 'W1634' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
9+
useless-option-value:20:0:None:None::"Useless option value for 'disable-next', 'no-self-use' was moved to an optional extension, see https://pylint.pycqa.org/en/latest/whatsnew/2/2.14/summary.html#removed-checkers.":HIGH
10+
useless-option-value:22:0:None:None::"Useless option value for 'disable-next', 'R0201' was moved to an optional extension, see https://pylint.pycqa.org/en/latest/whatsnew/2/2.14/summary.html#removed-checkers.":HIGH
11+
unknown-option-value:25:0:None:None::Unknown option value for 'enable', expected a valid pylint message and got 'W04044':HIGH
12+
useless-option-value:27:0:None:None::"Useless option value for 'enable', 'dict-values-not-iterating' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
13+
useless-option-value:29:0:None:None::"Useless option value for 'enable', 'no-self-use' was moved to an optional extension, see https://pylint.pycqa.org/en/latest/whatsnew/2/2.14/summary.html#removed-checkers.":HIGH
14+
useless-option-value:31:0:None:None::"Useless option value for 'enable', 'W1622' was removed from pylint, see https://github.com/PyCQA/pylint/pull/4942.":HIGH
15+
useless-option-value:33:0:None:None::"Useless option value for 'enable', 'R0201' was moved to an optional extension, see https://pylint.pycqa.org/en/latest/whatsnew/2/2.14/summary.html#removed-checkers.":HIGH
16+
useless-option-value:36:0:None:None::"Useless option value for 'disable', 'no-space-after-operator' was removed from pylint, see https://github.com/PyCQA/pylint/pull/3577.":HIGH
17+
useless-option-value:38:0:None:None::"Useless option value for 'disable', 'C0323' was removed from pylint, see https://github.com/PyCQA/pylint/pull/3577.":HIGH

0 commit comments

Comments
 (0)