Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7860,7 +7860,6 @@ def push_type_map(self, type_map: TypeMap, *, from_assignment: bool = True) -> N
def infer_issubclass_maps(self, node: CallExpr, expr: Expression) -> tuple[TypeMap, TypeMap]:
"""Infer type restrictions for an expression in issubclass call."""
vartype = self.lookup_type(expr)
type = self.get_isinstance_type(node.args[1])
if isinstance(vartype, TypeVarType):
vartype = vartype.upper_bound
vartype = get_proper_type(vartype)
Expand All @@ -7876,13 +7875,18 @@ def infer_issubclass_maps(self, node: CallExpr, expr: Expression) -> tuple[TypeM
vartype = UnionType(union_list)
elif isinstance(vartype, TypeType):
vartype = vartype.item
elif isinstance(vartype, AnyType):
pass
elif isinstance(vartype, Instance) and vartype.type.is_metaclass():
vartype = self.named_type("builtins.object")
else:
# Any other object whose type we don't know precisely
# for example, Any or a custom metaclass.
return {}, {} # unknown type
yes_type, no_type = self.conditional_types_with_intersection(vartype, type, expr)
# Any other object which isn't a type
return {}, {}

issubclass_type = self.get_isinstance_type(node.args[1])
yes_type, no_type = self.conditional_types_with_intersection(
vartype, issubclass_type, expr
)
yes_map, no_map = conditional_types_to_typemaps(expr, yes_type, no_type)
yes_map, no_map = map(convert_to_typetype, (yes_map, no_map))
return yes_map, no_map
Expand Down
19 changes: 19 additions & 0 deletions test-data/unit/check-isinstance.test
Original file line number Diff line number Diff line change
Expand Up @@ -1867,6 +1867,25 @@ def directed_meet(cls0: ClassT, cls1: ClassT) -> ClassT | None:
return None
[builtins fixtures/isinstancelist.pyi]

[case testIssubclassAny]
# flags: --warn-unreachable
from typing import Any

def f1(x: Any) -> None:
if issubclass(x, int):
reveal_type(x) # N: Revealed type is "type[builtins.int]"
else:
reveal_type(x) # N: Revealed type is "Any"
reveal_type(x) # N: Revealed type is "Any"

def f2(x: Any) -> None:
if issubclass(x, list):
reveal_type(x) # N: Revealed type is "type[builtins.list[Any]]"
else:
reveal_type(x) # N: Revealed type is "Any"
reveal_type(x) # N: Revealed type is "Any"
[builtins fixtures/isinstancelist.pyi]

[case testIsinstanceTypeArgs]
# flags: --warn-unreachable
from typing import Iterable, TypeVar
Expand Down
Loading