11from __future__ import annotations
22
3+ from typing import cast
4+
35from mypy .expandtype import expand_type , expand_type_by_instance
46from mypy .nodes import TypeInfo
57from mypy .types import AnyType , Instance , TupleType , Type , TypeOfAny , has_type_vars
68
79
8- def map_type_to_instance (typ : Type , target : Instance ) -> Instance | None :
9- """Attempt to map `typ` to an Instance of the same class as `target`
10-
11- Examples:
12- (list[int], Iterable[T]) -> Iterable[int]
13- (list[list[int]], Iterable[list[T]]) -> Iterable[list[int]]
14- (dict[str, int], Mapping[K, int]) -> Mapping[str, int]
15- (list[int], Mapping[K, V]) -> None
10+ def as_type (typ : Type , direction : int , target : Type ) -> Type | None :
11+ """Attempts to solve type variables in `target` so that `typ` is a subtype/supertype of
12+ the resulting type.
1613
1714 Args:
1815 typ: The type to map from.
16+ direction: One of SUBTYPE_OF or SUPERTYPE_OF
1917 target: The target instance type to map to.
2018
2119 Returns:
2220 None: if the mapping is not possible.
23- Instance: the mapped instance type if the mapping is possible.
21+ Type: the mapped type if the mapping is possible.
22+
23+ Examples:
24+ (list[int], Iterable[T]) -> Iterable[int]
25+ (list[list[int]], Iterable[list[T]]) -> Iterable[list[int]]
26+ (dict[str, int], Mapping[K, int]) -> Mapping[str, int]
27+ (list[int], Mapping[K, V]) -> None
2428 """
2529 from mypy .subtypes import is_subtype
2630 from mypy .typeops import get_all_type_vars
2731
2832 # 1. get type vars of target
2933 tvars = get_all_type_vars (target )
3034
31- # fast path: if no type vars,
35+ # fast path: if no type vars, just check subtype
3236 if not tvars :
3337 return target if is_subtype (typ , target ) else None
3438
35- from mypy .constraints import SUBTYPE_OF , SUPERTYPE_OF , Constraint , infer_constraints
39+ from mypy .constraints import SUBTYPE_OF , Constraint , infer_constraints
3640 from mypy .solve import solve_constraints
3741
3842 # 2. determine constraints
39- constraints : list [Constraint ] = infer_constraints (target , typ , SUPERTYPE_OF )
43+ constraints : list [Constraint ] = infer_constraints (target , typ , not direction )
4044 for tvar in tvars :
45+ # need to manually include these because solve_constraints ignores them
46+ # apparently
4147 constraints .append (Constraint (tvar , SUBTYPE_OF , tvar .upper_bound ))
4248
4349 # 3. solve constraints
@@ -46,8 +52,8 @@ def map_type_to_instance(typ: Type, target: Instance) -> Instance | None:
4652 if None in solution :
4753 return None
4854
49- # 4. build resulting Instance by substituting typevars with solution
50- env = {tvar .id : sol for tvar , sol in zip (tvars , solution )}
55+ # 4. build resulting Type by substituting type vars with solution
56+ env = {tvar .id : s for tvar , s in zip (tvars , cast ( "list[Type]" , solution ) )}
5157 target = expand_type (target , env )
5258 return target if is_subtype (typ , target ) else None
5359
0 commit comments