@@ -1020,6 +1020,105 @@ else:
10201020 reveal_type(true_or_false) # N: Revealed type is "Literal[False]"
10211021[builtins fixtures/primitives.pyi]
10221022
1023+
1024+ [case testNarrowingIsInstanceFinalSubclass]
1025+ # flags: --warn-unreachable
1026+
1027+ from typing import final
1028+
1029+ class N: ...
1030+ @final
1031+ class F1: ...
1032+ @final
1033+ class F2: ...
1034+
1035+ n: N
1036+ f1: F1
1037+
1038+ if isinstance(f1, F1):
1039+ reveal_type(f1) # N: Revealed type is "__main__.F1"
1040+ else:
1041+ reveal_type(f1) # E: Statement is unreachable
1042+
1043+ if isinstance(n, F1): # E: Subclass of "N" and "F1" cannot exist: "F1" is final
1044+ reveal_type(n) # E: Statement is unreachable
1045+ else:
1046+ reveal_type(n) # N: Revealed type is "__main__.N"
1047+
1048+ if isinstance(f1, N): # E: Subclass of "F1" and "N" cannot exist: "F1" is final
1049+ reveal_type(f1) # E: Statement is unreachable
1050+ else:
1051+ reveal_type(f1) # N: Revealed type is "__main__.F1"
1052+
1053+ if isinstance(f1, F2): # E: Subclass of "F1" and "F2" cannot exist: "F1" is final \
1054+ # E: Subclass of "F1" and "F2" cannot exist: "F2" is final
1055+ reveal_type(f1) # E: Statement is unreachable
1056+ else:
1057+ reveal_type(f1) # N: Revealed type is "__main__.F1"
1058+ [builtins fixtures/isinstance.pyi]
1059+
1060+
1061+ [case testNarrowingIsInstanceFinalSubclassWithUnions]
1062+ # flags: --warn-unreachable
1063+
1064+ from typing import final, Union
1065+
1066+ class N: ...
1067+ @final
1068+ class F1: ...
1069+ @final
1070+ class F2: ...
1071+
1072+ n_f1: Union[N, F1]
1073+ n_f2: Union[N, F2]
1074+ f1_f2: Union[F1, F2]
1075+
1076+ if isinstance(n_f1, F1):
1077+ reveal_type(n_f1) # N: Revealed type is "__main__.F1"
1078+ else:
1079+ reveal_type(n_f1) # N: Revealed type is "__main__.N"
1080+
1081+ if isinstance(n_f2, F1): # E: Subclass of "N" and "F1" cannot exist: "F1" is final \
1082+ # E: Subclass of "F2" and "F1" cannot exist: "F2" is final \
1083+ # E: Subclass of "F2" and "F1" cannot exist: "F1" is final
1084+ reveal_type(n_f2) # E: Statement is unreachable
1085+ else:
1086+ reveal_type(n_f2) # N: Revealed type is "Union[__main__.N, __main__.F2]"
1087+
1088+ if isinstance(f1_f2, F1):
1089+ reveal_type(f1_f2) # N: Revealed type is "__main__.F1"
1090+ else:
1091+ reveal_type(f1_f2) # N: Revealed type is "__main__.F2"
1092+ [builtins fixtures/isinstance.pyi]
1093+
1094+
1095+ [case testNarrowingIsSubclassFinalSubclassWithTypeVar]
1096+ # flags: --warn-unreachable
1097+
1098+ from typing import final, Type, TypeVar
1099+
1100+ @final
1101+ class A: ...
1102+ @final
1103+ class B: ...
1104+
1105+ T = TypeVar("T", A, B)
1106+
1107+ def f(cls: Type[T]) -> T:
1108+ if issubclass(cls, A):
1109+ reveal_type(cls) # N: Revealed type is "Type[__main__.A]"
1110+ x: bool
1111+ if x:
1112+ return A()
1113+ else:
1114+ return B() # E: Incompatible return value type (got "B", expected "A")
1115+ assert False
1116+
1117+ reveal_type(f(A)) # N: Revealed type is "__main__.A"
1118+ reveal_type(f(B)) # N: Revealed type is "__main__.B"
1119+ [builtins fixtures/isinstance.pyi]
1120+
1121+
10231122[case testNarrowingLiteralIdentityCheck]
10241123from typing import Union
10251124from typing_extensions import Literal
0 commit comments