UseIsNoneOnOptionalRule

Enforces explicit use of is None or is not None when checking whether an Optional has a value. Directly testing an object (e.g. if x) implicitely tests for a truth value which returns True unless the object’s __bool__() method returns False, its __len__() method returns ‘0’, or it is one of the constants None or False. (https://docs.python.org/3.8/library/stdtypes.html#truth-value-testing).

Message

When checking if an Optional has a value, avoid using it as a boolean since it implicitly checks the object’s __bool__(), __len__() is not 0, or the value is not None. Instead, use is None or is not None to be explicit.

Has Autofix: Yes

VALID Code Examples

# 1:

from typing import Optional
a: Optional[str]
if a is not None:
    pass

# 2:

a: bool
if a:
    pass

INVALID Code Examples

# 1:

from typing import Optional

a: Optional[str] = None
if a:
    pass

Autofix:

---
+++
@@ -2,5 +2,5 @@
 from typing import Optional

 a: Optional[str] = None
-if a:
+if a is not None:
     pass

# 2:

from typing import Optional
a: Optional[str] = None
x: bool = False
if x and a:
    ...

Autofix:

---
+++
@@ -2,5 +2,5 @@
 from typing import Optional
 a: Optional[str] = None
 x: bool = False
-if x and a:
+if x and a is not None:
     ...

# 3:

from typing import Optional
a: Optional[str] = None
x: bool = False
if a and x:
    ...

Autofix:

---
+++
@@ -2,5 +2,5 @@
 from typing import Optional
 a: Optional[str] = None
 x: bool = False
-if a and x:
+if a is not None and x:
     ...

# 4:

from typing import Optional
a: Optional[str] = None
x: bool = not a

Autofix:

---
+++
@@ -1,4 +1,4 @@

 from typing import Optional
 a: Optional[str] = None
-x: bool = not a
+x: bool = a is None

# 5:

from typing import Optional
a: Optional[str]
x: bool
if x or a: pass

Autofix:

---
+++
@@ -2,4 +2,4 @@
 from typing import Optional
 a: Optional[str]
 x: bool
-if x or a: pass
+if x or a is not None: pass

# 6:

from typing import Optional
a: Optional[str]
x: bool
if x: pass
elif a: pass

Autofix:

---
+++
@@ -3,4 +3,4 @@
 a: Optional[str]
 x: bool
 if x: pass
-elif a: pass
+elif a is not None: pass

# 7:

from typing import Optional
a: Optional[str] = None
b: Optional[str] = None
if a: pass
elif b: pass

Autofix:

---
+++
@@ -2,5 +2,5 @@
 from typing import Optional
 a: Optional[str] = None
 b: Optional[str] = None
-if a: pass
-elif b: pass
+if a is not None: pass
+elif b is not None: pass