|
115 | 115 | non_method_protocol_members,
|
116 | 116 | )
|
117 | 117 | from mypy.traverser import has_await_expression
|
118 |
| -from mypy.type_visitor import TypeTranslator |
119 | 118 | from mypy.typeanal import (
|
120 | 119 | check_for_explicit_any,
|
121 | 120 | fix_instance,
|
|
168 | 167 | TypeOfAny,
|
169 | 168 | TypeType,
|
170 | 169 | TypeVarId,
|
171 |
| - TypeVarLikeType, |
172 | 170 | TypeVarTupleType,
|
173 | 171 | TypeVarType,
|
174 | 172 | UnboundType,
|
|
182 | 180 | get_proper_types,
|
183 | 181 | has_recursive_types,
|
184 | 182 | is_named_instance,
|
185 |
| - remove_dups, |
186 | 183 | split_with_prefix_and_suffix,
|
187 | 184 | )
|
188 | 185 | from mypy.types_utils import (
|
@@ -2136,7 +2133,7 @@ def infer_function_type_arguments(
|
2136 | 2133 | )
|
2137 | 2134 | # Try applying inferred polymorphic type if possible, e.g. Callable[[T], T] can
|
2138 | 2135 | # be interpreted as def [T] (T) -> T, but dict[T, T] cannot be expressed.
|
2139 |
| - applied = apply_poly(poly_callee_type, free_vars) |
| 2136 | + applied = applytype.apply_poly(poly_callee_type, free_vars) |
2140 | 2137 | if applied is not None and all(
|
2141 | 2138 | a is not None and not isinstance(get_proper_type(a), UninhabitedType)
|
2142 | 2139 | for a in poly_inferred_args
|
@@ -6220,129 +6217,6 @@ def replace_callable_return_type(c: CallableType, new_ret_type: Type) -> Callabl
|
6220 | 6217 | return c.copy_modified(ret_type=new_ret_type)
|
6221 | 6218 |
|
6222 | 6219 |
|
6223 |
| -def apply_poly(tp: CallableType, poly_tvars: Sequence[TypeVarLikeType]) -> CallableType | None: |
6224 |
| - """Make free type variables generic in the type if possible. |
6225 |
| -
|
6226 |
| - This will translate the type `tp` while trying to create valid bindings for |
6227 |
| - type variables `poly_tvars` while traversing the type. This follows the same rules |
6228 |
| - as we do during semantic analysis phase, examples: |
6229 |
| - * Callable[Callable[[T], T], T] -> def [T] (def (T) -> T) -> T |
6230 |
| - * Callable[[], Callable[[T], T]] -> def () -> def [T] (T -> T) |
6231 |
| - * List[T] -> None (not possible) |
6232 |
| - """ |
6233 |
| - try: |
6234 |
| - return tp.copy_modified( |
6235 |
| - arg_types=[t.accept(PolyTranslator(poly_tvars)) for t in tp.arg_types], |
6236 |
| - ret_type=tp.ret_type.accept(PolyTranslator(poly_tvars)), |
6237 |
| - variables=[], |
6238 |
| - ) |
6239 |
| - except PolyTranslationError: |
6240 |
| - return None |
6241 |
| - |
6242 |
| - |
6243 |
| -class PolyTranslationError(Exception): |
6244 |
| - pass |
6245 |
| - |
6246 |
| - |
6247 |
| -class PolyTranslator(TypeTranslator): |
6248 |
| - """Make free type variables generic in the type if possible. |
6249 |
| -
|
6250 |
| - See docstring for apply_poly() for details. |
6251 |
| - """ |
6252 |
| - |
6253 |
| - def __init__( |
6254 |
| - self, |
6255 |
| - poly_tvars: Iterable[TypeVarLikeType], |
6256 |
| - bound_tvars: frozenset[TypeVarLikeType] = frozenset(), |
6257 |
| - seen_aliases: frozenset[TypeInfo] = frozenset(), |
6258 |
| - ) -> None: |
6259 |
| - self.poly_tvars = set(poly_tvars) |
6260 |
| - # This is a simplified version of TypeVarScope used during semantic analysis. |
6261 |
| - self.bound_tvars = bound_tvars |
6262 |
| - self.seen_aliases = seen_aliases |
6263 |
| - |
6264 |
| - def collect_vars(self, t: CallableType | Parameters) -> list[TypeVarLikeType]: |
6265 |
| - found_vars = [] |
6266 |
| - for arg in t.arg_types: |
6267 |
| - for tv in get_all_type_vars(arg): |
6268 |
| - if isinstance(tv, ParamSpecType): |
6269 |
| - normalized: TypeVarLikeType = tv.copy_modified( |
6270 |
| - flavor=ParamSpecFlavor.BARE, prefix=Parameters([], [], []) |
6271 |
| - ) |
6272 |
| - else: |
6273 |
| - normalized = tv |
6274 |
| - if normalized in self.poly_tvars and normalized not in self.bound_tvars: |
6275 |
| - found_vars.append(normalized) |
6276 |
| - return remove_dups(found_vars) |
6277 |
| - |
6278 |
| - def visit_callable_type(self, t: CallableType) -> Type: |
6279 |
| - found_vars = self.collect_vars(t) |
6280 |
| - self.bound_tvars |= set(found_vars) |
6281 |
| - result = super().visit_callable_type(t) |
6282 |
| - self.bound_tvars -= set(found_vars) |
6283 |
| - |
6284 |
| - assert isinstance(result, ProperType) and isinstance(result, CallableType) |
6285 |
| - result.variables = list(result.variables) + found_vars |
6286 |
| - return result |
6287 |
| - |
6288 |
| - def visit_type_var(self, t: TypeVarType) -> Type: |
6289 |
| - if t in self.poly_tvars and t not in self.bound_tvars: |
6290 |
| - raise PolyTranslationError() |
6291 |
| - return super().visit_type_var(t) |
6292 |
| - |
6293 |
| - def visit_param_spec(self, t: ParamSpecType) -> Type: |
6294 |
| - if t in self.poly_tvars and t not in self.bound_tvars: |
6295 |
| - raise PolyTranslationError() |
6296 |
| - return super().visit_param_spec(t) |
6297 |
| - |
6298 |
| - def visit_type_var_tuple(self, t: TypeVarTupleType) -> Type: |
6299 |
| - if t in self.poly_tvars and t not in self.bound_tvars: |
6300 |
| - raise PolyTranslationError() |
6301 |
| - return super().visit_type_var_tuple(t) |
6302 |
| - |
6303 |
| - def visit_type_alias_type(self, t: TypeAliasType) -> Type: |
6304 |
| - if not t.args: |
6305 |
| - return t.copy_modified() |
6306 |
| - if not t.is_recursive: |
6307 |
| - return get_proper_type(t).accept(self) |
6308 |
| - # We can't handle polymorphic application for recursive generic aliases |
6309 |
| - # without risking an infinite recursion, just give up for now. |
6310 |
| - raise PolyTranslationError() |
6311 |
| - |
6312 |
| - def visit_instance(self, t: Instance) -> Type: |
6313 |
| - if t.type.has_param_spec_type: |
6314 |
| - # We need this special-casing to preserve the possibility to store a |
6315 |
| - # generic function in an instance type. Things like |
6316 |
| - # forall T . Foo[[x: T], T] |
6317 |
| - # are not really expressible in current type system, but this looks like |
6318 |
| - # a useful feature, so let's keep it. |
6319 |
| - param_spec_index = next( |
6320 |
| - i for (i, tv) in enumerate(t.type.defn.type_vars) if isinstance(tv, ParamSpecType) |
6321 |
| - ) |
6322 |
| - p = get_proper_type(t.args[param_spec_index]) |
6323 |
| - if isinstance(p, Parameters): |
6324 |
| - found_vars = self.collect_vars(p) |
6325 |
| - self.bound_tvars |= set(found_vars) |
6326 |
| - new_args = [a.accept(self) for a in t.args] |
6327 |
| - self.bound_tvars -= set(found_vars) |
6328 |
| - |
6329 |
| - repl = new_args[param_spec_index] |
6330 |
| - assert isinstance(repl, ProperType) and isinstance(repl, Parameters) |
6331 |
| - repl.variables = list(repl.variables) + list(found_vars) |
6332 |
| - return t.copy_modified(args=new_args) |
6333 |
| - # There is the same problem with callback protocols as with aliases |
6334 |
| - # (callback protocols are essentially more flexible aliases to callables). |
6335 |
| - if t.args and t.type.is_protocol and t.type.protocol_members == ["__call__"]: |
6336 |
| - if t.type in self.seen_aliases: |
6337 |
| - raise PolyTranslationError() |
6338 |
| - call = find_member("__call__", t, t, is_operator=True) |
6339 |
| - assert call is not None |
6340 |
| - return call.accept( |
6341 |
| - PolyTranslator(self.poly_tvars, self.bound_tvars, self.seen_aliases | {t.type}) |
6342 |
| - ) |
6343 |
| - return super().visit_instance(t) |
6344 |
| - |
6345 |
| - |
6346 | 6220 | class ArgInferSecondPassQuery(types.BoolTypeQuery):
|
6347 | 6221 | """Query whether an argument type should be inferred in the second pass.
|
6348 | 6222 |
|
|
0 commit comments