Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions pylint/checkers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,16 @@ def overrides_a_method(class_node: nodes.ClassDef, name: str) -> bool:
return False


def check_messages(*messages: str) -> Callable:
"""Decorator to store messages that are handled by a checker method."""
def only_required_for(*messages: str) -> Callable:
"""Decorator to store messages that are handled by a checker method as an
attribute of the function object.

This information is used by ``ASTWalker`` to decide whether to call the decorated
method or not. If none of the messages is enabled, the method will be skipped.
Therefore, the list of messages must be well maintained at all times!
This decorator only has an effect on ``visit_*`` and ``leave_*`` methods
of a class inheriting from ``BaseChecker`` and implementing ``IAstroidChecker``.
"""

def store_messages(func):
func.checks_msgs = messages
Expand All @@ -444,6 +452,23 @@ def store_messages(func):
return store_messages


def check_messages(*messages: str) -> Callable:
"""Kept for backwards compatibility, deprecated.

Use only_required_for instead, which conveys the intent of the decorator much clearer.
"""
# Uncomment the following warning once all 'check_messages' calls have been replaced
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can activate it right now so we see if we migrated everything by seeing the warnings in tests :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this does not lead to a failed CI pipeline, we can activate it right away. 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for some deprecation warnings it's hard to deactivate them (or would take too much time to catch them everywhere), so warning do not make the CI fail.

# in pylints codebase.

# warnings.warn(
# "utils.check_messages will be removed in favour of calling "
# "utils.only_required_for in pylint 3.0",
# DeprecationWarning,
# )

return only_required_for(*messages)


class IncompleteFormatString(Exception):
"""A format string ended in the middle of a format specifier."""

Expand Down
14 changes: 7 additions & 7 deletions tests/utils/unittest_ast_walker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import astroid

from pylint.checkers.utils import check_messages
from pylint.checkers.utils import only_required_for
from pylint.utils import ASTWalker


Expand All @@ -23,23 +23,23 @@ class Checker:
def __init__(self) -> None:
self.called: Set[str] = set()

@check_messages("first-message")
@only_required_for("first-message")
def visit_module(self, module): # pylint: disable=unused-argument
self.called.add("module")

@check_messages("second-message")
@only_required_for("second-message")
def visit_call(self, module):
raise NotImplementedError

@check_messages("second-message", "third-message")
@only_required_for("second-message", "third-message")
def visit_assignname(self, module): # pylint: disable=unused-argument
self.called.add("assignname")

@check_messages("second-message")
@only_required_for("second-message")
def leave_assignname(self, module):
raise NotImplementedError

def test_check_messages(self) -> None:
def test_only_required_for(self) -> None:
linter = self.MockLinter(
{"first-message": True, "second-message": False, "third-message": True}
)
Expand All @@ -54,7 +54,7 @@ class Checker:
def __init__(self) -> None:
self.called = False

@check_messages("first-message")
@only_required_for("first-message")
def visit_assname(self, node): # pylint: disable=unused-argument
self.called = True

Expand Down