Skip to content
Merged
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/10161.false_positive
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Comparisons between two calls to `type()` won't raise an ``unidiomatic-typecheck`` warning anymore, consistent with the behavior applied only for ``==`` previously.

Closes #10161
15 changes: 5 additions & 10 deletions pylint/checkers/base/comparison_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,18 +323,13 @@ def _check_unidiomatic_typecheck(self, node: nodes.Compare) -> None:
if operator in TYPECHECK_COMPARISON_OPERATORS:
left = node.left
if _is_one_arg_pos_call(left):
self._check_type_x_is_y(node, left, operator, right)
self._check_type_x_is_y(node=node, left=left, right=right)
elif isinstance(left, nodes.Name) and _is_one_arg_pos_call(right):
self._check_type_x_is_y(
node=node, left=right, operator=operator, right=left
) # transforming Y == type(x) case to type(x) == Y
# transforming Y == type(x) case to type(x) == Y
self._check_type_x_is_y(node=node, left=right, right=left)

def _check_type_x_is_y(
self,
node: nodes.Compare,
left: nodes.NodeNG,
operator: str,
right: nodes.NodeNG,
self, node: nodes.Compare, left: nodes.NodeNG, right: nodes.NodeNG
) -> None:
"""Check for expressions like type(x) == Y."""
left_func = utils.safe_infer(left.func)
Expand All @@ -343,7 +338,7 @@ def _check_type_x_is_y(
):
return

if operator in {"is", "is not"} and _is_one_arg_pos_call(right):
if _is_one_arg_pos_call(right):
right_func = utils.safe_infer(right.func)
if (
isinstance(right_func, nodes.ClassDef)
Expand Down
28 changes: 21 additions & 7 deletions tests/functional/u/unidiomatic_typecheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,28 @@ def parameter_shadowing_inference_negatives(type):
type(42) in [int]
type(42) not in [int]

def deliberate_subclass_check_negatives(b):

def deliberate_subclass_check_negatives(a, b):
type(42) is type(b)
type(42) is not type(b)
type(42) == type(b)
type(42) != type(b)
type(a) is type(b)
type(a) is not type(b)
type(a) == type(b)
type(a) != 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]
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]
type(a) == type([]) # [unidiomatic-typecheck]
type(a) != type([]) # [unidiomatic-typecheck]
type(a) == type({}) # [unidiomatic-typecheck]
type(a) != type({}) # [unidiomatic-typecheck]
type(a) == type("") # [unidiomatic-typecheck]
type(a) != type("") # [unidiomatic-typecheck]
18 changes: 12 additions & 6 deletions tests/functional/u/unidiomatic_typecheck.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@ unidiomatic-typecheck:16:4:16:20:simple_inference_positives:Use isinstance() rat
unidiomatic-typecheck:17:4:17:24:simple_inference_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:18:4:18:20:simple_inference_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:19:4:19:20:simple_inference_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
unidiomatic-typecheck:71:4:71:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:72:4:72:27:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:73:4:73:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:74:4:74:27:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:77:4:77:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:78:4:78:27:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:79:4:79:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:80:4:80:27:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:81:4:81:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:82:4:82:27:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:83:4:83:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:84:4:84:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:85:4:85:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:86:4:86:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:87:4:87:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
unidiomatic-typecheck:88:4:88:23:type_of_literals_positives:Use isinstance() rather than type() for a typecheck.:UNDEFINED
Loading