Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[implicit_booleaness_checker] Add the confidence to related messages #7721

Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions .pyenchant_pylint_custom_dict.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ bla
bom
bool
boolean
booleaness
boolop
boundmethod
builtins
Expand Down Expand Up @@ -106,6 +107,7 @@ epytext
erroring
etree
expr
falsey
favour
filepath
filestream
Expand Down Expand Up @@ -326,6 +328,7 @@ toplevel
towncrier
tp
truthness
truthey
tryexcept
txt
typecheck
Expand Down
61 changes: 35 additions & 26 deletions pylint/checkers/refactoring/implicit_booleaness_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from pylint import checkers
from pylint.checkers import utils
from pylint.interfaces import HIGH, INFERENCE


class ImplicitBooleanessChecker(checkers.BaseChecker):
Expand Down Expand Up @@ -99,7 +100,11 @@ def visit_call(self, node: nodes.Call) -> None:
)
if isinstance(len_arg, generator_or_comprehension):
# The node is a generator or comprehension as in len([x for x in ...])
self.add_message("use-implicit-booleaness-not-len", node=node)
self.add_message(
"use-implicit-booleaness-not-len",
node=node,
confidence=HIGH,
)
return
try:
instance = next(len_arg.infer())
Expand All @@ -113,7 +118,11 @@ def visit_call(self, node: nodes.Call) -> None:
if "range" in mother_classes or (
affected_by_pep8 and not self.instance_has_bool(instance)
):
self.add_message("use-implicit-booleaness-not-len", node=node)
self.add_message(
"use-implicit-booleaness-not-len",
node=node,
confidence=INFERENCE,
)

@staticmethod
def instance_has_bool(class_def: nodes.ClassDef) -> bool:
Expand All @@ -134,7 +143,9 @@ def visit_unaryop(self, node: nodes.UnaryOp) -> None:
and node.op == "not"
and utils.is_call_of_name(node.operand, "len")
):
self.add_message("use-implicit-booleaness-not-len", node=node)
self.add_message(
"use-implicit-booleaness-not-len", node=node, confidence=HIGH
)

@utils.only_required_for_messages("use-implicit-booleaness-not-comparison")
def visit_compare(self, node: nodes.Compare) -> None:
Expand Down Expand Up @@ -177,35 +188,33 @@ def _check_use_implicit_booleaness_not_comparison(

# No need to check for operator when visiting compare node
if operator in {"==", "!=", ">=", ">", "<=", "<"}:
collection_literal = "{}"
if isinstance(literal_node, nodes.List):
collection_literal = "[]"
if isinstance(literal_node, nodes.Tuple):
collection_literal = "()"

instance_name = "x"
if isinstance(target_node, nodes.Call) and target_node.func:
instance_name = f"{target_node.func.as_string()}(...)"
elif isinstance(target_node, (nodes.Attribute, nodes.Name)):
instance_name = target_node.as_string()

original_comparison = (
f"{instance_name} {operator} {collection_literal}"
)
suggestion = (
f"{instance_name}"
if operator == "!="
else f"not {instance_name}"
)
self.add_message(
"use-implicit-booleaness-not-comparison",
args=(
original_comparison,
suggestion,
args=self._implicit_booleaness_message_args(
literal_node, operator, target_node
),
node=node,
confidence=HIGH,
)

def _implicit_booleaness_message_args(
self, literal_node: nodes.NodeNG, operator: str, target_node: nodes.NodeNG
) -> tuple[str, str]:
"""Helper to get the right message for "use-implicit-booleaness-not-comparison"."""
collection_literal = "{}"
if isinstance(literal_node, nodes.List):
collection_literal = "[]"
if isinstance(literal_node, nodes.Tuple):
collection_literal = "()"
instance_name = "x"
if isinstance(target_node, nodes.Call) and target_node.func:
instance_name = f"{target_node.func.as_string()}(...)"
elif isinstance(target_node, (nodes.Attribute, nodes.Name)):
instance_name = target_node.as_string()
original_comparison = f"{instance_name} {operator} {collection_literal}"
suggestion = f"{instance_name}" if operator == "!=" else f"not {instance_name}"
return original_comparison, suggestion

@staticmethod
def base_names_of_instance(node: bases.Uninferable | bases.Instance) -> list[str]:
"""Return all names inherited by a class instance or those returned by a
Expand Down
3 changes: 2 additions & 1 deletion pylint/extensions/comparetozero.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from pylint import checkers
from pylint.checkers import utils
from pylint.interfaces import HIGH

if TYPE_CHECKING:
from pylint.lint import PyLinter
Expand Down Expand Up @@ -70,7 +71,7 @@ def visit_compare(self, node: nodes.Compare) -> None:
error_detected = True

if error_detected:
self.add_message("compare-to-zero", node=node)
self.add_message("compare-to-zero", node=node, confidence=HIGH)


def register(linter: PyLinter) -> None:
Expand Down
3 changes: 2 additions & 1 deletion pylint/extensions/emptystring.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from pylint import checkers
from pylint.checkers import utils
from pylint.interfaces import HIGH

if TYPE_CHECKING:
from pylint.lint import PyLinter
Expand Down Expand Up @@ -64,7 +65,7 @@ def visit_compare(self, node: nodes.Compare) -> None:
error_detected = True

if error_detected:
self.add_message("compare-to-empty-string", node=node)
self.add_message("compare-to-empty-string", node=node, confidence=HIGH)


def register(linter: PyLinter) -> None:
Expand Down
8 changes: 4 additions & 4 deletions tests/functional/ext/comparetozero/comparetozero.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
compare-to-zero:6:3:6:9::Avoid comparisons to zero:UNDEFINED
compare-to-zero:9:3:9:13::Avoid comparisons to zero:UNDEFINED
compare-to-zero:12:3:12:9::Avoid comparisons to zero:UNDEFINED
compare-to-zero:15:3:15:9::Avoid comparisons to zero:UNDEFINED
compare-to-zero:6:3:6:9::Avoid comparisons to zero:HIGH
compare-to-zero:9:3:9:13::Avoid comparisons to zero:HIGH
compare-to-zero:12:3:12:9::Avoid comparisons to zero:HIGH
compare-to-zero:15:3:15:9::Avoid comparisons to zero:HIGH
8 changes: 4 additions & 4 deletions tests/functional/ext/emptystring/empty_string_comparison.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
compare-to-empty-string:6:3:6:10::Avoid comparisons to empty string:UNDEFINED
compare-to-empty-string:9:3:9:14::Avoid comparisons to empty string:UNDEFINED
compare-to-empty-string:12:3:12:10::Avoid comparisons to empty string:UNDEFINED
compare-to-empty-string:15:3:15:10::Avoid comparisons to empty string:UNDEFINED
compare-to-empty-string:6:3:6:10::Avoid comparisons to empty string:HIGH
compare-to-empty-string:9:3:9:14::Avoid comparisons to empty string:HIGH
compare-to-empty-string:12:3:12:10::Avoid comparisons to empty string:HIGH
compare-to-empty-string:15:3:15:10::Avoid comparisons to empty string:HIGH
64 changes: 32 additions & 32 deletions tests/functional/u/use/use_implicit_booleaness_not_comparison.txt
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
use-implicit-booleaness-not-comparison:14:7:14:21:github_issue_4774:'bad_list == []' can be simplified to 'not bad_list' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:22:3:22:20::'empty_tuple == ()' can be simplified to 'not empty_tuple' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:25:3:25:19::'empty_list == []' can be simplified to 'not empty_list' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:28:3:28:19::'empty_dict == {}' can be simplified to 'not empty_dict' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:31:3:31:20::'empty_tuple == ()' can be simplified to 'not empty_tuple' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:34:3:34:19::'empty_list == []' can be simplified to 'not empty_list' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:37:3:37:19::'empty_dict == {}' can be simplified to 'not empty_dict' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:42:11:42:18:bad_tuple_return:'t == ()' can be simplified to 'not t' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:46:11:46:18:bad_list_return:'b == []' can be simplified to 'not b' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:50:11:50:18:bad_dict_return:'c == {}' can be simplified to 'not c' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:52:7:52:24::'empty_tuple == ()' can be simplified to 'not empty_tuple' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:53:7:53:23::'empty_list == []' can be simplified to 'not empty_list' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:54:7:54:23::'empty_dict != {}' can be simplified to 'empty_dict' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:55:7:55:23::'empty_tuple < ()' can be simplified to 'not empty_tuple' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:56:7:56:23::'empty_list <= []' can be simplified to 'not empty_list' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:57:7:57:23::'empty_tuple > ()' can be simplified to 'not empty_tuple' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:58:7:58:23::'empty_list >= []' can be simplified to 'not empty_list' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:83:3:83:10::'a == []' can be simplified to 'not a' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:95:3:95:10::'e == []' can be simplified to 'not e' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:95:15:95:22::'f == {}' can be simplified to 'not f' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:133:3:133:14::'A.lst == []' can be simplified to 'not A.lst' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:137:3:137:14::'A.lst == []' can be simplified to 'not A.lst' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:141:3:141:20::'A.test(...) == []' can be simplified to 'not A.test(...)' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:149:3:149:24::'test_function(...) == []' can be simplified to 'not test_function(...)' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:156:3:156:20::'numpy_array == []' can be simplified to 'not numpy_array' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:158:3:158:20::'numpy_array != []' can be simplified to 'numpy_array' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:160:3:160:20::'numpy_array >= ()' can be simplified to 'not numpy_array' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:185:3:185:13::'data == {}' can be simplified to 'not data' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:187:3:187:13::'data != {}' can be simplified to 'data' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:195:3:195:26::'long_test == {}' can be simplified to 'not long_test' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:233:11:233:41:test_func:'my_class.parent_function == {}' can be simplified to 'not my_class.parent_function' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:234:11:234:37:test_func:'my_class.my_property == {}' can be simplified to 'not my_class.my_property' as an empty sequence is falsey:UNDEFINED
use-implicit-booleaness-not-comparison:14:7:14:21:github_issue_4774:'bad_list == []' can be simplified to 'not bad_list' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:22:3:22:20::'empty_tuple == ()' can be simplified to 'not empty_tuple' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:25:3:25:19::'empty_list == []' can be simplified to 'not empty_list' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:28:3:28:19::'empty_dict == {}' can be simplified to 'not empty_dict' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:31:3:31:20::'empty_tuple == ()' can be simplified to 'not empty_tuple' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:34:3:34:19::'empty_list == []' can be simplified to 'not empty_list' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:37:3:37:19::'empty_dict == {}' can be simplified to 'not empty_dict' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:42:11:42:18:bad_tuple_return:'t == ()' can be simplified to 'not t' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:46:11:46:18:bad_list_return:'b == []' can be simplified to 'not b' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:50:11:50:18:bad_dict_return:'c == {}' can be simplified to 'not c' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:52:7:52:24::'empty_tuple == ()' can be simplified to 'not empty_tuple' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:53:7:53:23::'empty_list == []' can be simplified to 'not empty_list' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:54:7:54:23::'empty_dict != {}' can be simplified to 'empty_dict' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:55:7:55:23::'empty_tuple < ()' can be simplified to 'not empty_tuple' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:56:7:56:23::'empty_list <= []' can be simplified to 'not empty_list' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:57:7:57:23::'empty_tuple > ()' can be simplified to 'not empty_tuple' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:58:7:58:23::'empty_list >= []' can be simplified to 'not empty_list' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:83:3:83:10::'a == []' can be simplified to 'not a' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:95:3:95:10::'e == []' can be simplified to 'not e' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:95:15:95:22::'f == {}' can be simplified to 'not f' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:133:3:133:14::'A.lst == []' can be simplified to 'not A.lst' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:137:3:137:14::'A.lst == []' can be simplified to 'not A.lst' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:141:3:141:20::'A.test(...) == []' can be simplified to 'not A.test(...)' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:149:3:149:24::'test_function(...) == []' can be simplified to 'not test_function(...)' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:156:3:156:20::'numpy_array == []' can be simplified to 'not numpy_array' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:158:3:158:20::'numpy_array != []' can be simplified to 'numpy_array' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:160:3:160:20::'numpy_array >= ()' can be simplified to 'not numpy_array' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:185:3:185:13::'data == {}' can be simplified to 'not data' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:187:3:187:13::'data != {}' can be simplified to 'data' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:195:3:195:26::'long_test == {}' can be simplified to 'not long_test' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:233:11:233:41:test_func:'my_class.parent_function == {}' can be simplified to 'not my_class.parent_function' as an empty sequence is falsey:HIGH
use-implicit-booleaness-not-comparison:234:11:234:37:test_func:'my_class.my_property == {}' can be simplified to 'not my_class.my_property' as an empty sequence is falsey:HIGH
Loading