Returns true if left and right are overlapping tuples.
(
left: Type, right: Type, is_overlapping: Callable[[Type, Type], bool]
)
| 708 | |
| 709 | |
| 710 | def are_tuples_overlapping( |
| 711 | left: Type, right: Type, is_overlapping: Callable[[Type, Type], bool] |
| 712 | ) -> bool: |
| 713 | """Returns true if left and right are overlapping tuples.""" |
| 714 | left, right = get_proper_types((left, right)) |
| 715 | left = adjust_tuple(left, right) or left |
| 716 | right = adjust_tuple(right, left) or right |
| 717 | assert isinstance(left, TupleType), f"Type {left} is not a tuple" |
| 718 | assert isinstance(right, TupleType), f"Type {right} is not a tuple" |
| 719 | |
| 720 | # This algorithm works well if only one tuple is variadic, if both are |
| 721 | # variadic we may get rare false negatives for overlapping prefix/suffix. |
| 722 | # Also, this ignores empty unpack case, but it is probably consistent with |
| 723 | # how we handle e.g. empty lists in overload overlaps. |
| 724 | # TODO: write a more robust algorithm for cases where both types are variadic. |
| 725 | left_unpack = find_unpack_in_list(left.items) |
| 726 | right_unpack = find_unpack_in_list(right.items) |
| 727 | if left_unpack is not None: |
| 728 | left = expand_tuple_if_possible(left, len(right.items)) |
| 729 | if right_unpack is not None: |
| 730 | right = expand_tuple_if_possible(right, len(left.items)) |
| 731 | |
| 732 | if len(left.items) != len(right.items): |
| 733 | return False |
| 734 | if not all(is_overlapping(l, r) for l, r in zip(left.items, right.items)): |
| 735 | return False |
| 736 | |
| 737 | # Check that the tuples aren't from e.g. different NamedTuples. |
| 738 | if is_named_instance(right.partial_fallback, "builtins.tuple") or is_named_instance( |
| 739 | left.partial_fallback, "builtins.tuple" |
| 740 | ): |
| 741 | return True |
| 742 | else: |
| 743 | return is_overlapping(left.partial_fallback, right.partial_fallback) |
| 744 | |
| 745 | |
| 746 | def expand_tuple_if_possible(tup: TupleType, target: int) -> TupleType: |
no test coverage detected
searching dependent graphs…