Skip to content

Commit

Permalink
Mark no-self-use as moved to extensions (#6932)
Browse files Browse the repository at this point in the history
* Mark `no-self-use` as deleted (moved to extensions)
* Separate notions of deleted messages from moved messages

Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
  • Loading branch information
jacobtylerwalls and Pierre-Sassoulas committed Jun 15, 2022
1 parent af3816b commit d6fa341
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 12 deletions.
5 changes: 4 additions & 1 deletion pylint/config/callback_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,10 @@ def _call(
for msgid in utils._check_csv(values[0]):
try:
xabling_function(msgid)
except exceptions.DeletedMessageError as e:
except (
exceptions.DeletedMessageError,
exceptions.MessageBecameExtensionError,
) as e:
self.linter._stashed_messages[
(self.linter.current_name, "useless-option-value")
].append((option_string, str(e)))
Expand Down
11 changes: 11 additions & 0 deletions pylint/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ def __init__(self, msgid_or_symbol: str, removal_explanation: str):
)


class MessageBecameExtensionError(UnknownMessageError):
"""Raised when a message id or symbol that was moved to an optional
extension is encountered.
"""

def __init__(self, msgid_or_symbol: str, moved_explanation: str):
super().__init__(
f"'{msgid_or_symbol}' was moved to an optional extension, see {moved_explanation}."
)


class EmptyReportError(Exception):
"""Raised when a report is empty and so should not be displayed."""

Expand Down
5 changes: 4 additions & 1 deletion pylint/lint/message_state_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,10 @@ def process_tokens(self, tokens: list[tokenize.TokenInfo]) -> None:
l_start -= 1
try:
meth(msgid, "module", l_start)
except exceptions.DeletedMessageError as e:
except (
exceptions.DeletedMessageError,
exceptions.MessageBecameExtensionError,
) as e:
self.linter.add_message(
"useless-option-value",
args=(pragma_repr.action, e),
Expand Down
29 changes: 29 additions & 0 deletions pylint/message/_deleted_message_ids.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ class DeletedMessage(NamedTuple):
DeletedMessage("W0111", "assign-to-new-keyword"),
],
}
MOVED_TO_EXTENSIONS = {
"https://pylint.pycqa.org/en/latest/whatsnew/2/2.14/summary.html#removed-checkers": [
DeletedMessage("R0201", "no-self-use")
],
}


@lru_cache(maxsize=None)
Expand All @@ -148,3 +153,27 @@ def is_deleted_msgid(msgid: str) -> str | None:
):
return explanation
return None


@lru_cache(maxsize=None)
def is_moved_symbol(symbol: str) -> str | None:
"""Return the explanation for moving if the message was moved to extensions."""
for explanation, moved_messages in MOVED_TO_EXTENSIONS.items():
for moved_message in moved_messages:
if symbol == moved_message.symbol or any(
symbol == m[1] for m in moved_message.old_names
):
return explanation
return None


@lru_cache(maxsize=None)
def is_moved_msgid(msgid: str) -> str | None:
"""Return the explanation for moving if the message was moved to extensions."""
for explanation, moved_messages in MOVED_TO_EXTENSIONS.items():
for moved_message in moved_messages:
if msgid == moved_message.msgid or any(
msgid == m[0] for m in moved_message.old_names
):
return explanation
return None
15 changes: 14 additions & 1 deletion pylint/message/message_id_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@
from pylint.exceptions import (
DeletedMessageError,
InvalidMessageError,
MessageBecameExtensionError,
UnknownMessageError,
)
from pylint.message._deleted_message_ids import is_deleted_msgid, is_deleted_symbol
from pylint.message._deleted_message_ids import (
is_deleted_msgid,
is_deleted_symbol,
is_moved_msgid,
is_moved_symbol,
)


class MessageIdStore:
Expand Down Expand Up @@ -128,20 +134,27 @@ def get_active_msgids(self, msgid_or_symbol: str) -> list[str]:
# If we don't have a cached value yet we compute it
msgid: str | None
deletion_reason = None
moved_reason = None
if msgid_or_symbol[1:].isdigit():
# Only msgid can have a digit as second letter
msgid = msgid_or_symbol.upper()
symbol = self.__msgid_to_symbol.get(msgid)
if not symbol:
deletion_reason = is_deleted_msgid(msgid)
if deletion_reason is None:
moved_reason = is_moved_msgid(msgid)
else:
symbol = msgid_or_symbol
msgid = self.__symbol_to_msgid.get(msgid_or_symbol)
if not msgid:
deletion_reason = is_deleted_symbol(symbol)
if deletion_reason is None:
moved_reason = is_moved_symbol(symbol)
if not msgid or not symbol:
if deletion_reason is not None:
raise DeletedMessageError(msgid_or_symbol, deletion_reason)
if moved_reason is not None:
raise MessageBecameExtensionError(msgid_or_symbol, moved_reason)
error_msg = f"No such message id or symbol '{msgid_or_symbol}'."
raise UnknownMessageError(error_msg)
ids = self.__old_names.get(msgid, [msgid])
Expand Down
12 changes: 12 additions & 0 deletions tests/functional/b/bad_option_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,33 @@
# pylint: disable=C05048 # [unknown-option-value]
# Standard disable with deleted symbol
# pylint: disable=execfile-builtin # [useless-option-value]
# Standard disable with symbol moved to extension
# pylint: disable=no-self-use # [useless-option-value]
# Standard disable with deleted msgid
# pylint: disable=W1656 # [useless-option-value]
# Standard disable with msgid moved to extension
# pylint: disable=R0201 # [useless-option-value]
# disable-next with unknown value
# pylint: disable-next=R78948 # [unknown-option-value]
# disable-next with deleted symbol
# pylint: disable-next=deprecated-types-field # [useless-option-value]
# disable-next with deleted msgid
# pylint: disable-next=W1634 # [useless-option-value]
# disable-next with symbol moved to extension
# pylint: disable-next=no-self-use # [useless-option-value]
# disable-next with msgid moved to extension
# pylint: disable-next=R0201 # [useless-option-value]

# enable with unknown value
# pylint:enable=W04044 # [unknown-option-value]
# enable with deleted symbol
# pylint:enable=dict-values-not-iterating # [useless-option-value]
# enable with symbol moved to extension
# pylint: enable=no-self-use # [useless-option-value]
# enable with deleted msgid
# pylint:enable=W1622 # [useless-option-value]
# enable with msgid moved to extension
# pylint: enable=R0201 # [useless-option-value]

# Standard disable with deleted old name symbol of deleted message
# pylint: disable=no-space-after-operator # [useless-option-value]
Expand Down
24 changes: 15 additions & 9 deletions tests/functional/b/bad_option_value.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
unknown-option-value:4:0:None:None::Unknown option value for 'disable', expected a valid pylint message and got 'C05048':HIGH
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
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
unknown-option-value:10:0:None:None::Unknown option value for 'disable-next', expected a valid pylint message and got 'R78948':HIGH
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
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
unknown-option-value:17:0:None:None::Unknown option value for 'enable', expected a valid pylint message and got 'W04044':HIGH
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
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
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
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
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
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
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
unknown-option-value:14:0:None:None::Unknown option value for 'disable-next', expected a valid pylint message and got 'R78948':HIGH
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
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
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
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
unknown-option-value:25:0:None:None::Unknown option value for 'enable', expected a valid pylint message and got 'W04044':HIGH
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
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
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
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
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
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 comments on commit d6fa341

Please sign in to comment.