MCPcopy
hub / github.com/python/mypy / is_subtype

Function is_subtype

mypy/subtypes.py:124–189  ·  view source on GitHub ↗

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,
)

Source from the content-addressed store, hash-verified

122
123
124def 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,

Calls 5

SubtypeContextClass · 0.85
pop_on_exitFunction · 0.85
_is_subtypeFunction · 0.85
is_assumed_subtypeMethod · 0.80
get_assumptionsMethod · 0.80

Tested by 6

test_subtype_aliasesMethod · 0.72
assert_simple_joinMethod · 0.72
assert_simple_meetMethod · 0.72
assert_subtypeMethod · 0.72
assert_not_subtypeMethod · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…