Skip to content

FURB168 false negative and false positives #15776

@dscorbett

Description

@dscorbett

Description

isinstance-type-none (FURB168) has a false negative and two false positives in Ruff 0.9.3.

The rule only triggers when the first argument to isinstance is an identifier. This is a false negative because any expression would work in that context.

$ cat >furb168_1.py <<'#EOF'
d = {"x": 1}
print(isinstance(d.get("x"), type(None)))
#EOF

$ python furb168_1.py
False

$ ruff --isolated check --preview --select FURB168 furb168_1.py
All checks passed!

If the expression consists purely of certain literals and operators, like 1 + 1, applying the FURB168 fix would produce a warning like SyntaxWarning: "is" with 'int' literal. Did you mean "=="?. That might be a reason the rule is currently so restricted, but I think it is better to apply the fix: the code is suspect either way but at least with the fix the user gets an explicit warning.

The first false positive is that the rule does not check whether type is the built-in type. (It does correctly check isinstance.)

$ cat >furb168_2.py <<'#EOF'
def type(x):
    return int
i = 1
print(isinstance(i, type(None)))
#EOF

$ python furb168_2.py
True

$ ruff --isolated check --preview --select FURB168 furb168_2.py --fix
Found 1 error (1 fixed, 0 remaining).

$ cat furb168_2.py
def type(x):
    return int
i = 1
print(i is None)

$ python furb168_2.py
False

The second false positive is that None | None is accepted as meaning type(None). That raises a TypeError which the fix suppresses.

$ cat >furb168_3.py <<'#EOF'
print(isinstance(abs, None | None))
#EOF

$ python furb168_3.py
Traceback (most recent call last):
  File "furb168_3.py", line 1, in <module>
    print(isinstance(abs, None | None))
                          ~~~~~^~~~~~
TypeError: unsupported operand type(s) for |: 'NoneType' and 'NoneType'

$ ruff --isolated check --preview --select FURB168 furb168_3.py --fix
Found 1 error (1 fixed, 0 remaining).

$ python furb168_3.py
False

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingruleImplementing or modifying a lint rule

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions