@@ -1420,7 +1420,8 @@ def visit_if_stmt(self, s: IfStmt) -> Type:
14201420 for e , b in zip (s .expr , s .body ):
14211421 t = self .accept (e )
14221422 self .check_not_void (t , e )
1423- var , type , elsetype , kind = find_isinstance_check (e , self .type_map )
1423+ var , type , elsetype , kind = find_isinstance_check (e , self .type_map ,
1424+ self .typing_mode_weak ())
14241425 if kind == ISINSTANCE_ALWAYS_FALSE :
14251426 # XXX should issue a warning?
14261427 pass
@@ -2032,7 +2033,8 @@ def map_type_from_supertype(typ: Type, sub_info: TypeInfo,
20322033
20332034
20342035def find_isinstance_check (node : Node ,
2035- type_map : Dict [Node , Type ]) -> Tuple [Node , Type , Type , int ]:
2036+ type_map : Dict [Node , Type ],
2037+ weak : bool = False ) -> Tuple [Node , Type , Type , int ]:
20362038 """Check if node is an isinstance(variable, type) check.
20372039
20382040 If successful, return tuple (variable, target-type, else-type,
@@ -2046,14 +2048,18 @@ def find_isinstance_check(node: Node,
20462048 variable type => the test is always True.
20472049 ISINSTANCE_ALWAYS_FALSE: The target type and the variable type are not
20482050 overlapping => the test is always False.
2051+
2052+ If it is an isinstance check, but we don't understand the argument
2053+ type, then in weak mode it is treated as Any and in non-weak mode
2054+ it is not treated as an isinstance.
20492055 """
20502056 if isinstance (node , CallExpr ):
20512057 if refers_to_fullname (node .callee , 'builtins.isinstance' ):
20522058 expr = node .args [0 ]
20532059 if expr .literal == LITERAL_TYPE :
2060+ vartype = type_map [expr ]
20542061 type = get_isinstance_type (node .args [1 ], type_map )
20552062 if type :
2056- vartype = type_map [expr ]
20572063 kind = ISINSTANCE_OVERLAPPING
20582064 elsetype = vartype
20592065 if vartype :
@@ -2065,6 +2071,20 @@ def find_isinstance_check(node: Node,
20652071 else :
20662072 elsetype = restrict_subtype_away (vartype , type )
20672073 return expr , type , elsetype , kind
2074+ else :
2075+ # An isinstance check, but we don't understand the type
2076+ if weak :
2077+ return expr , AnyType (), vartype , ISINSTANCE_OVERLAPPING
2078+ elif isinstance (node , OpExpr ) and node .op == 'and' :
2079+ # XXX We should extend this to support two isinstance checks in the same
2080+ # expression
2081+ (var , type , elsetype , kind ) = find_isinstance_check (node .left , type_map , weak )
2082+ if var is None :
2083+ (var , type , elsetype , kind ) = find_isinstance_check (node .left , type_map , weak )
2084+ if var :
2085+ if kind == ISINSTANCE_ALWAYS_TRUE :
2086+ kind = ISINSTANCE_OVERLAPPING
2087+ return (var , type , AnyType (), kind )
20682088 # Not a supported isinstance check
20692089 return None , AnyType (), AnyType (), - 1
20702090
0 commit comments