Reports typing.cast calls where the source and target types are unrelated.

An error is reported when neither the source type is a subtype of the target, nor the target type is a subtype of the source. Such casts often indicate a logical error, as an instance of one type cannot be assumed to be an instance of the other, and typing.cast does not dynamically validate the type.

This check applies even to types that could theoretically have a common descendant. For example, it will flag a cast between two sibling classes Left and Right that both inherit from Top, because there is no direct inheritance relationship between them.

Example:


from typing import cast

# Non-overlapping types — likely a mistake
cast(int, "a")          # 'str' -> 'int'
cast(list[int], ["a"])  # 'list[str]' -> 'list[int]'

# Recommended explicit escape hatch is to use a "double cast"
cast(int, cast(object, "a"))  # ok

# Legitimate overlapping cases
cast(int, object())    # a valid down cast
cast(object, 1)        # a valid up cast

# While the following is an invalid cast, as list is invariant. It's not currently supported by this inspection
int_list = [1, 2, 3]
cast(list[object], int_list)

The inspection relies on static type information; when a type is unknown, no warning is reported. Variance of generic types is not yet considered.