Return the greatest lower bound of two types.
(s: Type, t: Type)
| 72 | |
| 73 | |
| 74 | def meet_types(s: Type, t: Type) -> ProperType: |
| 75 | """Return the greatest lower bound of two types.""" |
| 76 | if is_recursive_pair(s, t): |
| 77 | # This case can trigger an infinite recursion, general support for this will be |
| 78 | # tricky, so we use a trivial meet (like for protocols). |
| 79 | return trivial_meet(s, t) |
| 80 | s = get_proper_type(s) |
| 81 | t = get_proper_type(t) |
| 82 | |
| 83 | if isinstance(s, Instance) and isinstance(t, Instance) and s.type == t.type: |
| 84 | # Code in checker.py should merge any extra_items where possible, so we |
| 85 | # should have only compatible extra_items here. We check this before |
| 86 | # the below subtype check, so that extra_attrs will not get erased. |
| 87 | if (s.extra_attrs or t.extra_attrs) and is_same_type(s, t): |
| 88 | if s.extra_attrs and t.extra_attrs: |
| 89 | if len(s.extra_attrs.attrs) > len(t.extra_attrs.attrs): |
| 90 | # Return the one that has more precise information. |
| 91 | return s |
| 92 | return t |
| 93 | if s.extra_attrs: |
| 94 | return s |
| 95 | return t |
| 96 | |
| 97 | if not isinstance(s, UnboundType) and not isinstance(t, UnboundType): |
| 98 | if is_proper_subtype(s, t, ignore_promotions=True): |
| 99 | return s |
| 100 | if is_proper_subtype(t, s, ignore_promotions=True): |
| 101 | return t |
| 102 | |
| 103 | if isinstance(s, ErasedType): |
| 104 | return s |
| 105 | if isinstance(s, AnyType): |
| 106 | return t |
| 107 | if isinstance(s, UnionType) and not isinstance(t, UnionType): |
| 108 | s, t = t, s |
| 109 | |
| 110 | # Meets/joins require callable type normalization. |
| 111 | s, t = join.normalize_callables(s, t) |
| 112 | |
| 113 | return t.accept(TypeMeetVisitor(s)) |
| 114 | |
| 115 | |
| 116 | def narrow_declared_type(declared: Type, narrowed: Type) -> Type: |
searching dependent graphs…