diff --git a/doc/whatsnew/fragments/10161.false_positive b/doc/whatsnew/fragments/10161.false_positive new file mode 100644 index 0000000000..f8c7540c8e --- /dev/null +++ b/doc/whatsnew/fragments/10161.false_positive @@ -0,0 +1,3 @@ +Fix a false positive for `unidiomatic-typecheck` when comparing two direct types. + +Closes #10161 diff --git a/pylint/checkers/base/comparison_checker.py b/pylint/checkers/base/comparison_checker.py index 6fb053e2e1..726cb376ee 100644 --- a/pylint/checkers/base/comparison_checker.py +++ b/pylint/checkers/base/comparison_checker.py @@ -339,15 +339,12 @@ def _check_type_x_is_y( ): return - if operator in {"is", "is not"} and _is_one_arg_pos_call(right): + if operator in {"!=", "==", "is", "is not"} and _is_one_arg_pos_call(right): right_func = utils.safe_infer(right.func) if ( isinstance(right_func, nodes.ClassDef) and right_func.qname() == TYPE_QNAME ): # type(x) == type(a) - right_arg = utils.safe_infer(right.args[0]) - if not isinstance(right_arg, LITERAL_NODE_TYPES): - # not e.g. type(x) == type([]) - return + return self.add_message("unidiomatic-typecheck", node=node) diff --git a/tests/functional/u/unidiomatic_typecheck.py b/tests/functional/u/unidiomatic_typecheck.py index 2a1957d75e..825b52f74a 100644 --- a/tests/functional/u/unidiomatic_typecheck.py +++ b/tests/functional/u/unidiomatic_typecheck.py @@ -61,10 +61,22 @@ def deliberate_subclass_check_negatives(b): type(42) is type(b) type(42) is not type(b) -def type_of_literals_positives(a): - type(a) is type([]) # [unidiomatic-typecheck] - type(a) is not type([]) # [unidiomatic-typecheck] - type(a) is type({}) # [unidiomatic-typecheck] - type(a) is not type({}) # [unidiomatic-typecheck] - type(a) is type("") # [unidiomatic-typecheck] - type(a) is not type("") # [unidiomatic-typecheck] +def type_of_literals_negatives(a): + type(a) is type([]) + type(a) is not type([]) + type(a) is type({}) + type(a) is not type({}) + type(a) is type("") + type(a) is not type("") + type(a) == type([]) + type(a) != type([]) + type(a) == type({}) + type(a) != type({}) + type(a) == type("") + type(a) != type("") + +def double_type_check_negatives(a, b): + type(a) == type(b) + type(a) != type(b) + type(a) is type(b) + type(a) is not type(b) diff --git a/tests/functional/u/unidiomatic_typecheck.txt b/tests/functional/u/unidiomatic_typecheck.txt index 84f5021d96..1a8e9b4d6c 100644 --- a/tests/functional/u/unidiomatic_typecheck.txt +++ b/tests/functional/u/unidiomatic_typecheck.txt @@ -6,9 +6,3 @@ unidiomatic-typecheck:12:4:12:20:simple_inference_positives:Use isinstance() rat unidiomatic-typecheck:13:4:13:24:simple_inference_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED unidiomatic-typecheck:14:4:14:20:simple_inference_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED unidiomatic-typecheck:15:4:15:20:simple_inference_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED -unidiomatic-typecheck:65:4:65:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED -unidiomatic-typecheck:66:4:66:27:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED -unidiomatic-typecheck:67:4:67:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED -unidiomatic-typecheck:68:4:68:27:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED -unidiomatic-typecheck:69:4:69:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED -unidiomatic-typecheck:70:4:70:27:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED