Is 'left' subtype of 'right'? Also consider Any to be a subtype of any type, and vice versa. This recursively applies to components of composite types (List[int] is subtype of List[Any], for example). type_parameter_checker is used to check the type parameters (for example, A w
(
left: Type,
right: Type,
*,
subtype_context: SubtypeContext | None = None,
ignore_type_params: bool = False,
ignore_pos_arg_names: bool = False,
ignore_declared_variance: bool = False,
always_covariant: bool = False,
ignore_promotions: bool = False,
options: Options | None = None,
)
| 122 | |
| 123 | |
| 124 | def is_subtype( |
| 125 | left: Type, |
| 126 | right: Type, |
| 127 | *, |
| 128 | subtype_context: SubtypeContext | None = None, |
| 129 | ignore_type_params: bool = False, |
| 130 | ignore_pos_arg_names: bool = False, |
| 131 | ignore_declared_variance: bool = False, |
| 132 | always_covariant: bool = False, |
| 133 | ignore_promotions: bool = False, |
| 134 | options: Options | None = None, |
| 135 | ) -> bool: |
| 136 | """Is 'left' subtype of 'right'? |
| 137 | |
| 138 | Also consider Any to be a subtype of any type, and vice versa. This |
| 139 | recursively applies to components of composite types (List[int] is subtype |
| 140 | of List[Any], for example). |
| 141 | |
| 142 | type_parameter_checker is used to check the type parameters (for example, |
| 143 | A with B in is_subtype(C[A], C[B]). The default checks for subtype relation |
| 144 | between the type arguments (e.g., A and B), taking the variance of the |
| 145 | type var into account. |
| 146 | """ |
| 147 | if left == right: |
| 148 | return True |
| 149 | if subtype_context is None: |
| 150 | subtype_context = SubtypeContext( |
| 151 | ignore_type_params=ignore_type_params, |
| 152 | ignore_pos_arg_names=ignore_pos_arg_names, |
| 153 | ignore_declared_variance=ignore_declared_variance, |
| 154 | always_covariant=always_covariant, |
| 155 | ignore_promotions=ignore_promotions, |
| 156 | options=options, |
| 157 | ) |
| 158 | else: |
| 159 | assert ( |
| 160 | not ignore_type_params |
| 161 | and not ignore_pos_arg_names |
| 162 | and not ignore_declared_variance |
| 163 | and not always_covariant |
| 164 | and not ignore_promotions |
| 165 | and options is None |
| 166 | ), "Don't pass both context and individual flags" |
| 167 | if type_state.is_assumed_subtype(left, right): |
| 168 | return True |
| 169 | if mypy.typeops.is_recursive_pair(left, right): |
| 170 | # This case requires special care because it may cause infinite recursion. |
| 171 | # Our view on recursive types is known under a fancy name of iso-recursive mu-types. |
| 172 | # Roughly this means that a recursive type is defined as an alias where right hand side |
| 173 | # can refer to the type as a whole, for example: |
| 174 | # A = Union[int, Tuple[A, ...]] |
| 175 | # and an alias unrolled once represents the *same type*, in our case all these represent |
| 176 | # the same type: |
| 177 | # A |
| 178 | # Union[int, Tuple[A, ...]] |
| 179 | # Union[int, Tuple[Union[int, Tuple[A, ...]], ...]] |
| 180 | # The algorithm for subtyping is then essentially under the assumption that left <: right, |
| 181 | # check that get_proper_type(left) <: get_proper_type(right). On the example above, |
searching dependent graphs…