@@ -410,26 +410,29 @@ def _remove_redundant_union_items(items: List[ProperType], keep_erased: bool) ->
410
410
411
411
# Keep track of the truishness info for deleted subtypes which can be relevant
412
412
cbt = cbf = False
413
- num_items = len (items )
414
413
for j , tj in enumerate (items ):
415
- if i != j :
416
- # NB: The first check below is an optimization to
417
- # avoid very expensive computations with large
418
- # unions involving literals. We approximate the
419
- # results for unions with many items. This is
420
- # "fine" since simplifying these union items is
421
- # (almost) always optional.
422
- if (
423
- (num_items < 5
424
- or is_likely_literal_supertype (item )
425
- or not is_simple_literal (tj ))
426
- and is_proper_subtype (tj , item , keep_erased_types = keep_erased )
427
- and is_redundant_literal_instance (item , tj ) # XXX?
428
- ):
429
- # We found a redundant item in the union.
430
- removed .add (j )
431
- cbt = cbt or tj .can_be_true
432
- cbf = cbf or tj .can_be_false
414
+ if (
415
+ i == j
416
+ # avoid further checks if this item was already marked redundant.
417
+ or j in removed
418
+ # if the current item is a simple literal then this simplification loop can
419
+ # safely skip all other simple literals as two literals will only ever be
420
+ # subtypes of each other if they are equal, which is already handled above.
421
+ # However, if the current item is not a literal, it might plausibly be a
422
+ # supertype of other literals in the union, so we must check them again.
423
+ # This is an important optimization as is_proper_subtype is pretty expensive.
424
+ or (k is not None and is_simple_literal (tj ))
425
+ ):
426
+ continue
427
+ # actual redundancy checks
428
+ if (
429
+ is_redundant_literal_instance (item , tj ) # XXX?
430
+ and is_proper_subtype (tj , item , keep_erased_types = keep_erased )
431
+ ):
432
+ # We found a redundant item in the union.
433
+ removed .add (j )
434
+ cbt = cbt or tj .can_be_true
435
+ cbf = cbf or tj .can_be_false
433
436
# if deleted subtypes had more general truthiness, use that
434
437
if not item .can_be_true and cbt :
435
438
items [i ] = true_or_false (item )
@@ -439,12 +442,6 @@ def _remove_redundant_union_items(items: List[ProperType], keep_erased: bool) ->
439
442
return [items [i ] for i in range (len (items )) if i not in removed ]
440
443
441
444
442
- def is_likely_literal_supertype (t : ProperType ) -> bool :
443
- """Is the type likely to cause simplification of literal types in unions?"""
444
- return isinstance (t , Instance ) and t .type .fullname in ('builtins.object' ,
445
- 'builtins.str' )
446
-
447
-
448
445
def _get_type_special_method_bool_ret_type (t : Type ) -> Optional [Type ]:
449
446
t = get_proper_type (t )
450
447
0 commit comments