@@ -1129,6 +1129,7 @@ def check_overload_call(self,
1129
1129
erased_targets = None # type: Optional[List[CallableType]]
1130
1130
unioned_result = None # type: Optional[Tuple[Type, Type]]
1131
1131
unioned_errors = None # type: Optional[MessageBuilder]
1132
+ union_success = False
1132
1133
if any (isinstance (arg , UnionType ) and len (arg .relevant_items ()) > 1 # "real" union
1133
1134
for arg in arg_types ):
1134
1135
erased_targets = self .overload_erased_call_targets (plausible_targets , arg_types ,
@@ -1142,18 +1143,26 @@ def check_overload_call(self,
1142
1143
arg_messages = unioned_errors ,
1143
1144
callable_name = callable_name ,
1144
1145
object_type = object_type )
1145
- if not unioned_errors . is_errors ():
1146
- # Success! Stop early .
1147
- return unioned_result
1146
+ # Record if we succeeded. Next we need to see if maybe normal procedure
1147
+ # gives a narrower type .
1148
+ union_success = unioned_result is not None and not unioned_errors . is_errors ()
1148
1149
1149
- # Step 3: If the union math fails, or if there was no union in the argument types,
1150
- # we fall back to checking each branch one-by-one.
1150
+ # Step 3: We try checking each branch one-by-one.
1151
1151
inferred_result = self .infer_overload_return_type (plausible_targets , args , arg_types ,
1152
1152
arg_kinds , arg_names , callable_name ,
1153
1153
object_type , context , arg_messages )
1154
1154
if inferred_result is not None :
1155
- # Success! Stop early.
1156
- return inferred_result
1155
+ # Success! Stop early by returning the best among normal and unioned.
1156
+ if not union_success :
1157
+ return inferred_result
1158
+ else :
1159
+ assert unioned_result is not None
1160
+ if is_subtype (inferred_result [0 ], unioned_result [0 ]):
1161
+ return inferred_result
1162
+ return unioned_result
1163
+ elif union_success :
1164
+ assert unioned_result is not None
1165
+ return unioned_result
1157
1166
1158
1167
# Step 4: Failure. At this point, we know there is no match. We fall back to trying
1159
1168
# to find a somewhat plausible overload target using the erased types
0 commit comments