diff options
author | Pierre Sassoulas <pierre.sassoulas@gmail.com> | 2022-11-09 21:08:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-09 20:08:32 +0000 |
commit | a0461a4546c42b4a5c25f314702fab331031048e (patch) | |
tree | f4c5c8db66263c4a0b97059267d0765b4a99cec6 /pylint/extensions | |
parent | 0e3a0da1d7cf62affb6196ee4713ad4f5c54f6f8 (diff) | |
download | pylint-git-a0461a4546c42b4a5c25f314702fab331031048e.tar.gz |
[compare-to-empty-string] More actionnable and understandable message (#7726)
We have to use " as string delimiter because node as string have ' as
string delimiter.
Diffstat (limited to 'pylint/extensions')
-rw-r--r-- | pylint/extensions/emptystring.py | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/pylint/extensions/emptystring.py b/pylint/extensions/emptystring.py index 5ff4ccb6d..f96a980f5 100644 --- a/pylint/extensions/emptystring.py +++ b/pylint/extensions/emptystring.py @@ -20,18 +20,10 @@ if TYPE_CHECKING: class CompareToEmptyStringChecker(checkers.BaseChecker): - """Checks for comparisons to empty string. - - Most of the time you should use the fact that empty strings are false. - An exception to this rule is when an empty string value is allowed in the program - and has a different meaning than None! - """ - - # configuration section name name = "compare-to-empty-string" msgs = { "C1901": ( - "Avoid comparisons to empty string", + '"%s" can be simplified to "%s" as an empty string is falsey', "compare-to-empty-string", "Used when Pylint detects comparison to an empty string constant.", ) @@ -41,31 +33,45 @@ class CompareToEmptyStringChecker(checkers.BaseChecker): @utils.only_required_for_messages("compare-to-empty-string") def visit_compare(self, node: nodes.Compare) -> None: - _operators = ["!=", "==", "is not", "is"] - # note: astroid.Compare has the left most operand in node.left - # while the rest are a list of tuples in node.ops - # the format of the tuple is ('compare operator sign', node) - # here we squash everything into `ops` to make it easier for processing later + """Checks for comparisons to empty string. + + Most of the time you should use the fact that empty strings are false. + An exception to this rule is when an empty string value is allowed in the program + and has a different meaning than None! + """ + _operators = {"!=", "==", "is not", "is"} + # note: astroid.Compare has the left most operand in node.left while the rest + # are a list of tuples in node.ops the format of the tuple is + # ('compare operator sign', node) here we squash everything into `ops` + # to make it easier for processing later ops: list[tuple[str, nodes.NodeNG | None]] = [("", node.left)] ops.extend(node.ops) iter_ops = iter(ops) ops = list(itertools.chain(*iter_ops)) # type: ignore[arg-type] - for ops_idx in range(len(ops) - 2): op_1: nodes.NodeNG | None = ops[ops_idx] op_2: str = ops[ops_idx + 1] # type: ignore[assignment] op_3: nodes.NodeNG | None = ops[ops_idx + 2] error_detected = False - + if op_1 is None or op_3 is None or op_2 not in _operators: + continue + node_name = "" # x ?? "" - if utils.is_empty_str_literal(op_1) and op_2 in _operators: + if utils.is_empty_str_literal(op_1): error_detected = True + node_name = op_3.as_string() # '' ?? X - elif op_2 in _operators and utils.is_empty_str_literal(op_3): + elif utils.is_empty_str_literal(op_3): error_detected = True - + node_name = op_1.as_string() if error_detected: - self.add_message("compare-to-empty-string", node=node, confidence=HIGH) + suggestion = f"not {node_name}" if op_2 in {"==", "is"} else node_name + self.add_message( + "compare-to-empty-string", + args=(node.as_string(), suggestion), + node=node, + confidence=HIGH, + ) def register(linter: PyLinter) -> None: |