@@ -318,6 +318,15 @@ def simple_literal_value_key(t: ProperType) -> Optional[Tuple[str, ...]]:
318
318
return None
319
319
320
320
321
+ def is_simple_literal (t : ProperType ) -> bool :
322
+ """Fast way to check if simple_literal_value_key() would return a non-None value."""
323
+ if isinstance (t , LiteralType ):
324
+ return t .fallback .type .is_enum or t .fallback .type .fullname == 'builtins.str'
325
+ if isinstance (t , Instance ):
326
+ return t .last_known_value is not None and isinstance (t .last_known_value .value , str )
327
+ return False
328
+
329
+
321
330
def make_simplified_union (items : Sequence [Type ],
322
331
line : int = - 1 , column : int = - 1 ,
323
332
* , keep_erased : bool = False ,
@@ -392,17 +401,26 @@ def _remove_redundant_union_items(items: List[ProperType], keep_erased: bool) ->
392
401
393
402
# Keep track of the truishness info for deleted subtypes which can be relevant
394
403
cbt = cbf = False
404
+ num_items = len (items )
395
405
for j , tj in enumerate (items ):
396
- # NB: we don't need to check literals as the fast path above takes care of that
397
- if (
398
- i != j
406
+ if i != j :
407
+ # NB: The first check below is an optimization to
408
+ # avoid very expensive computations with large
409
+ # unions involving literals. We approximate the
410
+ # results for unions with many items. This is
411
+ # "fine" since simplifying these union items is
412
+ # (almost) always optional.
413
+ if (
414
+ (num_items < 5
415
+ or is_likely_literal_supertype (item )
416
+ or not is_simple_literal (tj ))
399
417
and is_proper_subtype (tj , item , keep_erased_types = keep_erased )
400
418
and is_redundant_literal_instance (item , tj ) # XXX?
401
- ):
402
- # We found a redundant item in the union.
403
- removed .add (j )
404
- cbt = cbt or tj .can_be_true
405
- cbf = cbf or tj .can_be_false
419
+ ):
420
+ # We found a redundant item in the union.
421
+ removed .add (j )
422
+ cbt = cbt or tj .can_be_true
423
+ cbf = cbf or tj .can_be_false
406
424
# if deleted subtypes had more general truthiness, use that
407
425
if not item .can_be_true and cbt :
408
426
items [i ] = true_or_false (item )
@@ -412,6 +430,12 @@ def _remove_redundant_union_items(items: List[ProperType], keep_erased: bool) ->
412
430
return [items [i ] for i in range (len (items )) if i not in removed ]
413
431
414
432
433
+ def is_likely_literal_supertype (t : ProperType ) -> bool :
434
+ """Is the type likely to cause simplification of literal types in unions?"""
435
+ return isinstance (t , Instance ) and t .type .fullname in ('builtins.object' ,
436
+ 'builtins.str' )
437
+
438
+
415
439
def _get_type_special_method_bool_ret_type (t : Type ) -> Optional [Type ]:
416
440
t = get_proper_type (t )
417
441
0 commit comments