Skip to content

Commit

Permalink
Fix isinstance-second-argument-not-valid-type for union types with None
Browse files Browse the repository at this point in the history
(cherry picked from commit b5f2b01)
  • Loading branch information
Rogdham authored and DanielNoord committed Apr 7, 2023
1 parent ed67cc8 commit bcceff6
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 9 deletions.
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/8424.false_positive
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix false positive for isinstance-second-argument-not-valid-type when union types contains None.

Closes #8424
13 changes: 8 additions & 5 deletions pylint/checkers/typecheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
is_mapping,
is_module_ignored,
is_node_in_type_annotation_context,
is_none,
is_overload_stub,
is_postponed_evaluation_enabled,
is_super,
Expand Down Expand Up @@ -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:
Expand All @@ -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


Expand Down
6 changes: 5 additions & 1 deletion tests/functional/i/isinstance_second_argument_py310.py
Original file line number Diff line number Diff line change
@@ -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)

Expand Down
6 changes: 3 additions & 3 deletions tests/functional/i/isinstance_second_argument_py310.txt
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit bcceff6

Please sign in to comment.