Refine `ti` by replacing Anys in it with information taken from `si` This basically works by, when the types have the same structure, traversing both of them in parallel and replacing Any on the left with whatever the type on the right is. If the types don't have the same structure
(ti: Type, si: Type)
| 952 | |
| 953 | |
| 954 | def refine_type(ti: Type, si: Type) -> Type: |
| 955 | """Refine `ti` by replacing Anys in it with information taken from `si` |
| 956 | |
| 957 | This basically works by, when the types have the same structure, |
| 958 | traversing both of them in parallel and replacing Any on the left |
| 959 | with whatever the type on the right is. If the types don't have the |
| 960 | same structure (or aren't supported), the left type is chosen. |
| 961 | |
| 962 | For example: |
| 963 | refine(Any, T) = T, for all T |
| 964 | refine(float, int) = float |
| 965 | refine(List[Any], List[int]) = List[int] |
| 966 | refine(Dict[int, Any], Dict[Any, int]) = Dict[int, int] |
| 967 | refine(Tuple[int, Any], Tuple[Any, int]) = Tuple[int, int] |
| 968 | |
| 969 | refine(Callable[[Any], Any], Callable[[int], int]) = Callable[[int], int] |
| 970 | refine(Callable[..., int], Callable[[int, float], Any]) = Callable[[int, float], int] |
| 971 | |
| 972 | refine(Optional[Any], int) = Optional[int] |
| 973 | refine(Optional[Any], Optional[int]) = Optional[int] |
| 974 | refine(Optional[Any], Union[int, str]) = Optional[Union[int, str]] |
| 975 | refine(Optional[List[Any]], List[int]) = List[int] |
| 976 | |
| 977 | """ |
| 978 | t = get_proper_type(ti) |
| 979 | s = get_proper_type(si) |
| 980 | |
| 981 | if isinstance(t, AnyType): |
| 982 | # If s is also an Any, we return if it is a missing_import Any |
| 983 | return t if isinstance(s, AnyType) and t.missing_import_name else s |
| 984 | |
| 985 | if isinstance(t, Instance) and isinstance(s, Instance) and t.type == s.type: |
| 986 | return t.copy_modified(args=[refine_type(ta, sa) for ta, sa in zip(t.args, s.args)]) |
| 987 | |
| 988 | if ( |
| 989 | isinstance(t, TupleType) |
| 990 | and isinstance(s, TupleType) |
| 991 | and t.partial_fallback == s.partial_fallback |
| 992 | and len(t.items) == len(s.items) |
| 993 | ): |
| 994 | return t.copy_modified(items=[refine_type(ta, sa) for ta, sa in zip(t.items, s.items)]) |
| 995 | |
| 996 | if isinstance(t, CallableType) and isinstance(s, CallableType): |
| 997 | return refine_callable(t, s) |
| 998 | |
| 999 | if isinstance(t, UnionType): |
| 1000 | return refine_union(t, s) |
| 1001 | |
| 1002 | # TODO: Refining of builtins.tuple, Type? |
| 1003 | |
| 1004 | return t |
| 1005 | |
| 1006 | |
| 1007 | def refine_union(t: UnionType, s: ProperType) -> Type: |
no test coverage detected
searching dependent graphs…