Skip to content

Commit

Permalink
Detect x is True or x is False in FURB191
Browse files Browse the repository at this point in the history
  • Loading branch information
dosisod committed Mar 19, 2024
1 parent 66889f6 commit 589afd6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
22 changes: 19 additions & 3 deletions refurb/checks/readability/use_isinstance_bool.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from dataclasses import dataclass

from mypy.nodes import ComparisonExpr, Expression, ListExpr, NameExpr, SetExpr, TupleExpr
from mypy.nodes import ComparisonExpr, Expression, ListExpr, NameExpr, OpExpr, SetExpr, TupleExpr

from refurb.checks.common import stringify
from refurb.checks.common import extract_binary_oper, is_equivalent, stringify
from refurb.error import Error


Expand Down Expand Up @@ -49,7 +49,7 @@ def is_false(expr: Expression) -> bool:
return False


def check(node: ComparisonExpr, errors: list[Error]) -> None:
def check(node: ComparisonExpr | OpExpr, errors: list[Error]) -> None:
match node:
case ComparisonExpr(
operators=["in" | "not in" as op],
Expand All @@ -67,3 +67,19 @@ def check(node: ComparisonExpr, errors: list[Error]) -> None:
msg = f"Replace `{old}` with `{new}`"

errors.append(ErrorInfo.from_node(node, msg))

case OpExpr():
match extract_binary_oper("or", node):
case (
ComparisonExpr(operands=[lhs, t], operators=["is"]),
ComparisonExpr(operands=[rhs, f], operators=["is"]),
) if (
is_equivalent(lhs, rhs)
and ((is_true(t) and is_false(f)) or (is_false(t) and is_true(f)))
):
old = stringify(node)
new = f"isinstance({stringify(lhs)}, bool)"

msg = f"Replace `{old}` with `{new}`"

errors.append(ErrorInfo.from_node(node, msg))
18 changes: 18 additions & 0 deletions test/data/err_191.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

if b not in {True, False}: pass

_ = b is True or b is False # noqa: FURB149
_ = b is False or b is True # noqa: FURB149


# these should not
if b in {True}: pass # noqa: FURB171
Expand All @@ -52,3 +55,18 @@
if b == {True, False}: pass
if b == {False, True}: pass
if b == [True, False]: pass

b2 = False

_ = b is True or b is True # noqa: FURB149
_ = b is False or b is False # noqa: FURB149
_ = b is True or b is True # noqa: FURB149
_ = b is True or b is b2 # noqa: FURB149
_ = b is b2 or b is True # noqa: FURB149
_ = b is True or b2 is False # noqa: FURB149
_ = b is not True or b is False # noqa: FURB149
_ = b is False or b is not True # noqa: FURB149

# TODO: support this later
_ = x is not True and x is not False # noqa: FURB149
_ = x is not False and x is not True # noqa: FURB149
2 changes: 2 additions & 0 deletions test/data/err_191.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ test/data/err_191.py:20:15 [FURB191]: Replace `b in (True, False)` with `isinsta
test/data/err_191.py:23:7 [FURB191]: Replace `b in {True, False}` with `isinstance(b, bool)`
test/data/err_191.py:26:8 [FURB191]: Replace `b in {True, False}` with `isinstance(b, bool)`
test/data/err_191.py:28:4 [FURB191]: Replace `b not in {True, False}` with `not isinstance(b, bool)`
test/data/err_191.py:30:5 [FURB191]: Replace `b is True or b is False` with `isinstance(b, bool)`
test/data/err_191.py:31:5 [FURB191]: Replace `b is False or b is True` with `isinstance(b, bool)`

0 comments on commit 589afd6

Please sign in to comment.