Skip to content

Commit 9bd1247

Browse files
committed
Don't emit message for 'x < 0 or x > 100'
1 parent 2216859 commit 9bd1247

File tree

3 files changed

+37
-20
lines changed

3 files changed

+37
-20
lines changed

pylint/extensions/code_style.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import difflib
88
from copy import copy
9+
from enum import IntFlag, auto
910
from typing import TYPE_CHECKING, TypeGuard, cast
1011

1112
from astroid import nodes
@@ -18,6 +19,12 @@
1819
from pylint.lint import PyLinter
1920

2021

22+
class InvertibleValues(IntFlag):
23+
NO = 0
24+
YES = auto()
25+
EXPLICIT_NEGATION = auto()
26+
27+
2128
class CodeStyleChecker(BaseChecker):
2229
"""Checkers that can improve code consistency.
2330
@@ -366,16 +373,21 @@ def visit_assign(self, node: nodes.Assign) -> None:
366373
)
367374

368375
@staticmethod
369-
def _can_be_inverted(node: nodes.NodeNG) -> bool:
370-
match node:
371-
case nodes.UnaryOp(op="not"):
372-
return True
373-
case nodes.Compare(
374-
ops=[("!=" | "not in", _)]
375-
| [("<" | "<=" | ">" | ">=", nodes.Const(value=int()))]
376-
):
377-
return True
378-
return False
376+
def _can_be_inverted(values: list[nodes.NodeNG]) -> InvertibleValues:
377+
invertible = InvertibleValues.NO
378+
for node in values:
379+
match node:
380+
case nodes.UnaryOp(op="not") | nodes.Compare(
381+
ops=[("!=" | "not in", _)]
382+
):
383+
invertible |= InvertibleValues.EXPLICIT_NEGATION
384+
case nodes.Compare(
385+
ops=[("<" | "<=" | ">" | ">=", nodes.Const(value=int()))]
386+
):
387+
invertible |= InvertibleValues.YES
388+
case _:
389+
return InvertibleValues.NO
390+
return invertible
379391

380392
@staticmethod
381393
def _invert_node(node: nodes.NodeNG) -> nodes.NodeNG:
@@ -408,7 +420,11 @@ def _invert_node(node: nodes.NodeNG) -> nodes.NodeNG:
408420

409421
@only_required_for_messages("improve-conditionals")
410422
def visit_boolop(self, node: nodes.BoolOp) -> None:
411-
if node.op == "or" and all(self._can_be_inverted(val) for val in node.values):
423+
if (
424+
node.op == "or"
425+
and (invertible := self._can_be_inverted(node.values))
426+
and invertible & InvertibleValues.EXPLICIT_NEGATION
427+
):
412428
new_boolop = copy(node)
413429
new_boolop.op = "and"
414430
new_boolop.postinit([self._invert_node(val) for val in node.values])

tests/functional/ext/code_style/cs_improve_conditionals.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ def f1(expr, node_cls, x, y, z):
1212
elif not isinstance(expr, node_cls) or expr.attrname == "__init__":
1313
...
1414

15-
if not isinstance(expr, node_cls) or expr.attrname != "__init__": # [improve-conditionals]
15+
if x < 0 or x > 100:
16+
...
17+
elif x > 0 or y >= 1:
1618
...
17-
elif x > 0 or y >= 1: # [improve-conditionals]
19+
elif x < 0 or y <= 1:
1820
...
19-
elif x < 0 or y <= 1: # [improve-conditionals]
21+
22+
if not isinstance(expr, node_cls) or expr.attrname != "__init__": # [improve-conditionals]
2023
...
2124
elif not x or y not in z: # [improve-conditionals]
2225
...
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
improve-conditionals:15:7:15:68:f1:Rewrite conditional expression to 'not (isinstance(expr, node_cls) and expr.attrname == '__init__')':HIGH
2-
improve-conditionals:17:9:17:24:f1:Rewrite conditional expression to 'not (x <= 0 and y < 1)':HIGH
3-
improve-conditionals:19:9:19:24:f1:Rewrite conditional expression to 'not (x >= 0 and y > 1)':HIGH
4-
improve-conditionals:21:9:21:28:f1:Rewrite conditional expression to 'not (x and y in z)':HIGH
5-
improve-conditionals:23:9:23:29:f1:Rewrite conditional expression to 'x and y':HIGH
6-
improve-conditionals:25:16:25:30:f1:Rewrite conditional expression to 'not (y and z)':HIGH
1+
improve-conditionals:22:7:22:68:f1:Rewrite conditional expression to 'not (isinstance(expr, node_cls) and expr.attrname == '__init__')':HIGH
2+
improve-conditionals:24:9:24:28:f1:Rewrite conditional expression to 'not (x and y in z)':HIGH
3+
improve-conditionals:26:9:26:29:f1:Rewrite conditional expression to 'x and y':HIGH
4+
improve-conditionals:28:16:28:30:f1:Rewrite conditional expression to 'not (y and z)':HIGH

0 commit comments

Comments
 (0)