Skip to content

Commit 2c16cae

Browse files
[compare-to-empty-string] More actionnable and understandable message
We have to use " as string delimiter because node as string have ' as string delimiter.
1 parent f5f9e26 commit 2c16cae

File tree

2 files changed

+30
-24
lines changed

2 files changed

+30
-24
lines changed

pylint/extensions/emptystring.py

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,10 @@
2020

2121

2222
class CompareToEmptyStringChecker(checkers.BaseChecker):
23-
"""Checks for comparisons to empty string.
24-
25-
Most of the time you should use the fact that empty strings are false.
26-
An exception to this rule is when an empty string value is allowed in the program
27-
and has a different meaning than None!
28-
"""
29-
30-
# configuration section name
3123
name = "compare-to-empty-string"
3224
msgs = {
3325
"C1901": (
34-
"Avoid comparisons to empty string",
26+
'"%s" can be simplified to "%s" as an empty string is falsey',
3527
"compare-to-empty-string",
3628
"Used when Pylint detects comparison to an empty string constant.",
3729
)
@@ -41,31 +33,45 @@ class CompareToEmptyStringChecker(checkers.BaseChecker):
4133

4234
@utils.only_required_for_messages("compare-to-empty-string")
4335
def visit_compare(self, node: nodes.Compare) -> None:
44-
_operators = ["!=", "==", "is not", "is"]
45-
# note: astroid.Compare has the left most operand in node.left
46-
# while the rest are a list of tuples in node.ops
47-
# the format of the tuple is ('compare operator sign', node)
48-
# here we squash everything into `ops` to make it easier for processing later
36+
"""Checks for comparisons to empty string.
37+
38+
Most of the time you should use the fact that empty strings are false.
39+
An exception to this rule is when an empty string value is allowed in the program
40+
and has a different meaning than None!
41+
"""
42+
_operators = {"!=", "==", "is not", "is"}
43+
# note: astroid.Compare has the left most operand in node.left while the rest
44+
# are a list of tuples in node.ops the format of the tuple is
45+
# ('compare operator sign', node) here we squash everything into `ops`
46+
# to make it easier for processing later
4947
ops: list[tuple[str, nodes.NodeNG | None]] = [("", node.left)]
5048
ops.extend(node.ops)
5149
iter_ops = iter(ops)
5250
ops = list(itertools.chain(*iter_ops)) # type: ignore[arg-type]
53-
5451
for ops_idx in range(len(ops) - 2):
5552
op_1: nodes.NodeNG | None = ops[ops_idx]
5653
op_2: str = ops[ops_idx + 1] # type: ignore[assignment]
5754
op_3: nodes.NodeNG | None = ops[ops_idx + 2]
5855
error_detected = False
59-
56+
if op_1 is None or op_3 is None or op_2 not in _operators:
57+
continue
58+
node_name = ""
6059
# x ?? ""
61-
if utils.is_empty_str_literal(op_1) and op_2 in _operators:
60+
if utils.is_empty_str_literal(op_1):
6261
error_detected = True
62+
node_name = op_3.as_string()
6363
# '' ?? X
64-
elif op_2 in _operators and utils.is_empty_str_literal(op_3):
64+
elif utils.is_empty_str_literal(op_3):
6565
error_detected = True
66-
66+
node_name = op_1.as_string()
6767
if error_detected:
68-
self.add_message("compare-to-empty-string", node=node, confidence=HIGH)
68+
suggestion = f"not {node_name}" if op_2 in {"==", "is"} else node_name
69+
self.add_message(
70+
"compare-to-empty-string",
71+
args=(node.as_string(), suggestion),
72+
node=node,
73+
confidence=HIGH,
74+
)
6975

7076

7177
def register(linter: PyLinter) -> None:
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
compare-to-empty-string:6:3:6:10::Avoid comparisons to empty string:HIGH
2-
compare-to-empty-string:9:3:9:14::Avoid comparisons to empty string:HIGH
3-
compare-to-empty-string:12:3:12:10::Avoid comparisons to empty string:HIGH
4-
compare-to-empty-string:15:3:15:10::Avoid comparisons to empty string:HIGH
1+
compare-to-empty-string:6:3:6:10::"""X is ''"" can be simplified to ""not X"" as an empty string is falsey":HIGH
2+
compare-to-empty-string:9:3:9:14::"""Y is not ''"" can be simplified to ""Y"" as an empty string is falsey":HIGH
3+
compare-to-empty-string:12:3:12:10::"""X == ''"" can be simplified to ""not X"" as an empty string is falsey":HIGH
4+
compare-to-empty-string:15:3:15:10::"""Y != ''"" can be simplified to ""Y"" as an empty string is falsey":HIGH

0 commit comments

Comments
 (0)