diff --git a/ChangeLog b/ChangeLog index fe03477cc7..9373ddfe01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,10 +7,9 @@ What's New in Pylint 2.5.0? Release date: TBA -* Add a check for cases where the second argument to `isinstance` - is not a type. +* Add a check for cases where the second argument to `isinstance` is not a type. - Close #3308 + Close #3308 * Add 'notes-rgx' option, to be used for fixme check. diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index cc709e95be..7504121275 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -678,6 +678,19 @@ def _is_c_extension(module_node): ) +def _is_invalid_isinstance_type(arg): + # Return True if we are sure that arg is not a type + inferred = utils.safe_infer(arg) + if not inferred: + # Cannot infer it so skip it. + return False + if isinstance(inferred, astroid.Tuple): + return any(_is_invalid_isinstance_type(elt) for elt in inferred.elts) + if isinstance(inferred, astroid.ClassDef): + return False + return True + + class TypeChecker(BaseChecker): """try to find bugs in the code using type inference """ @@ -1177,17 +1190,8 @@ def _check_isinstance_args(self, node): # isinstance called with wrong number of args return - def is_not_type(arg): - # Return True if we are sure that arg is not a type - if isinstance(utils.safe_infer(arg), astroid.FunctionDef): - return True - if isinstance(arg, astroid.Tuple): - return any([is_not_type(elt) for elt in arg.elts]) - - return False - second_arg = node.args[1] - if is_not_type(second_arg): + if _is_invalid_isinstance_type(second_arg): self.add_message("isinstance-second-argument-not-valid-type", node=node) # pylint: disable=too-many-branches,too-many-locals diff --git a/tests/functional/i/isinstance_second_argument.py b/tests/functional/i/isinstance_second_argument.py index 71f8fedec2..62a721b687 100644 --- a/tests/functional/i/isinstance_second_argument.py +++ b/tests/functional/i/isinstance_second_argument.py @@ -26,3 +26,4 @@ class B(A): isinstance(64, hex) # [isinstance-second-argument-not-valid-type] isinstance({b: 100}, (hash, dict)) # [isinstance-second-argument-not-valid-type] isinstance("string", ((dict, iter), str, (int, bool))) # [isinstance-second-argument-not-valid-type] +isinstance(int, 1) # [isinstance-second-argument-not-valid-type] diff --git a/tests/functional/i/isinstance_second_argument.txt b/tests/functional/i/isinstance_second_argument.txt index 41ba2fd5bf..7893d2658f 100644 --- a/tests/functional/i/isinstance_second_argument.txt +++ b/tests/functional/i/isinstance_second_argument.txt @@ -2,3 +2,4 @@ isinstance-second-argument-not-valid-type:25::Second argument of isinstance is n isinstance-second-argument-not-valid-type:26::Second argument of isinstance is not a type isinstance-second-argument-not-valid-type:27::Second argument of isinstance is not a type isinstance-second-argument-not-valid-type:28::Second argument of isinstance is not a type +isinstance-second-argument-not-valid-type:29::Second argument of isinstance is not a type