Add eval_type_call which gets the result type of a function call at type check time.#41
Add eval_type_call which gets the result type of a function call at type check time.#41
Conversation
a2541b7 to
1124f8e
Compare
typemap/type_eval/_eval_call.py
Outdated
| def _substitute_type_vars( | ||
| obj: typing.Any, vars: dict[str, RtType] | ||
| ) -> typing.Any: | ||
| """Recursively substitute type variables into a type expression.""" | ||
| if isinstance(obj, typing.TypeVar): | ||
| return vars[obj.__name__] | ||
| elif _typing_inspect.is_generic_alias(obj): | ||
| args = tuple(_substitute_type_vars(v, vars) for v in obj.__args__) | ||
| return obj.__origin__[args] # type: ignore[index] | ||
| else: | ||
| return obj |
There was a problem hiding this comment.
Basically exactly this function exists in _apply_generic.py
typemap/type_eval/_eval_call.py
Outdated
| def eval_type_call( | ||
| callable: typing.Any, | ||
| *arg_types: Any, | ||
| **kwarg_types: Any, | ||
| ) -> RtType: |
There was a problem hiding this comment.
There is a lot of overlap between this and eval_call_with_types; I think that they need to either get merged or the overlap needs to be clarified a bit.
This version handles Callables in addition to actual functions, and evals everything. I think it handles actual functions less well, though, because Iter and Sub will get evaluated on typevars and not do anything useful. (Try calling it on select from test_qblike; this is why _eval_call_with_type_vars does all that crap to replace the typevars in the annotation closure with the real values)
So I guess either make this only handle typing.Callable and document both functions or fully merge it with eval_call_with_type_vars
There was a problem hiding this comment.
I figure the most straightforward thing here is to just add the Callable functionality to the existing function.
b0a9102 to
15c30d3
Compare
For example, given:
we can evaluate the result type of when calling func on arguments of known types.