summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRogdham <contact@rogdham.net>2023-04-07 18:54:23 +0200
committerDaniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>2023-04-07 21:50:41 +0200
commitb5f2b01635edd23fecc1546f3fdb2a41e6a51995 (patch)
tree32e1a46c1587893dc70baf4bcf7b6055708ec1a5
parentcb255eaaed8bba6bec1f7bf5d4cde15821c1dd46 (diff)
downloadpylint-git-b5f2b01635edd23fecc1546f3fdb2a41e6a51995.tar.gz
Fix isinstance-second-argument-not-valid-type for union types with None
-rw-r--r--doc/whatsnew/fragments/8424.false_positive3
-rw-r--r--pylint/checkers/typecheck.py13
-rw-r--r--tests/functional/i/isinstance_second_argument_py310.py6
-rw-r--r--tests/functional/i/isinstance_second_argument_py310.txt6
4 files changed, 19 insertions, 9 deletions
diff --git a/doc/whatsnew/fragments/8424.false_positive b/doc/whatsnew/fragments/8424.false_positive
new file mode 100644
index 000000000..22dc8b844
--- /dev/null
+++ b/doc/whatsnew/fragments/8424.false_positive
@@ -0,0 +1,3 @@
+Fix false positive for isinstance-second-argument-not-valid-type when union types contains None.
+
+Closes #8424
diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py
index 42131f936..7605d6b67 100644
--- a/pylint/checkers/typecheck.py
+++ b/pylint/checkers/typecheck.py
@@ -37,6 +37,7 @@ from pylint.checkers.utils import (
is_mapping,
is_module_ignored,
is_node_in_type_annotation_context,
+ is_none,
is_overload_stub,
is_postponed_evaluation_enabled,
is_super,
@@ -798,8 +799,9 @@ def _is_c_extension(module_node: InferenceResult) -> bool:
def _is_invalid_isinstance_type(arg: nodes.NodeNG) -> bool:
# Return True if we are sure that arg is not a type
if PY310_PLUS and isinstance(arg, nodes.BinOp) and arg.op == "|":
- return _is_invalid_isinstance_type(arg.left) or _is_invalid_isinstance_type(
- arg.right
+ return any(
+ _is_invalid_isinstance_type(elt) and not is_none(elt)
+ for elt in (arg.left, arg.right)
)
inferred = utils.safe_infer(arg)
if not inferred:
@@ -812,9 +814,10 @@ def _is_invalid_isinstance_type(arg: nodes.NodeNG) -> bool:
if isinstance(inferred, astroid.Instance) and inferred.qname() == BUILTIN_TUPLE:
return False
if PY310_PLUS and isinstance(inferred, bases.UnionType):
- return _is_invalid_isinstance_type(
- inferred.left
- ) or _is_invalid_isinstance_type(inferred.right)
+ return any(
+ _is_invalid_isinstance_type(elt) and not is_none(elt)
+ for elt in (inferred.left, inferred.right)
+ )
return True
diff --git a/tests/functional/i/isinstance_second_argument_py310.py b/tests/functional/i/isinstance_second_argument_py310.py
index 8a0c17af5..ad2033b31 100644
--- a/tests/functional/i/isinstance_second_argument_py310.py
+++ b/tests/functional/i/isinstance_second_argument_py310.py
@@ -1,13 +1,17 @@
-'''Tests for invalid isinstance with compound types'''
+"""Tests for invalid isinstance with compound types"""
# True negatives
isinstance(0, int | str)
isinstance(0, int | int | int)
isinstance(0, int | str | list | float)
isinstance(0, (int | str) | (list | float))
+isinstance(0, int | None)
+isinstance(0, None | int)
IntOrStr = int | str
isinstance(0, IntOrStr)
+IntOrNone = int | None
+isinstance(0, IntOrNone)
ListOrDict = list | dict
isinstance(0, (float | ListOrDict) | IntOrStr)
diff --git a/tests/functional/i/isinstance_second_argument_py310.txt b/tests/functional/i/isinstance_second_argument_py310.txt
index 776bf3c2e..aa50da29d 100644
--- a/tests/functional/i/isinstance_second_argument_py310.txt
+++ b/tests/functional/i/isinstance_second_argument_py310.txt
@@ -1,3 +1,3 @@
-isinstance-second-argument-not-valid-type:15:0:15:22::Second argument of isinstance is not a type:INFERENCE
-isinstance-second-argument-not-valid-type:16:0:16:28::Second argument of isinstance is not a type:INFERENCE
-isinstance-second-argument-not-valid-type:18:0:18:24::Second argument of isinstance is not a type:INFERENCE
+isinstance-second-argument-not-valid-type:19:0:19:22::Second argument of isinstance is not a type:INFERENCE
+isinstance-second-argument-not-valid-type:20:0:20:28::Second argument of isinstance is not a type:INFERENCE
+isinstance-second-argument-not-valid-type:22:0:22:24::Second argument of isinstance is not a type:INFERENCE