Skip to content

Add eval_type_call which gets the result type of a function call at type check time.#41

Merged
dnwpark merged 6 commits intomainfrom
eval-type-call
Jan 20, 2026
Merged

Add eval_type_call which gets the result type of a function call at type check time.#41
dnwpark merged 6 commits intomainfrom
eval-type-call

Conversation

@dnwpark
Copy link
Contributor

@dnwpark dnwpark commented Jan 15, 2026

For example, given:

    def func[T](x: T) -> T: ...

we can evaluate the result type of when calling func on arguments of known types.

    res = eval_type_call(func, int)
    assert res is int

Comment on lines +203 to +213
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically exactly this function exists in _apply_generic.py

Comment on lines +172 to +176
def eval_type_call(
callable: typing.Any,
*arg_types: Any,
**kwarg_types: Any,
) -> RtType:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figure the most straightforward thing here is to just add the Callable functionality to the existing function.

@dnwpark dnwpark merged commit f6e36a9 into main Jan 20, 2026
6 checks passed
@dnwpark dnwpark deleted the eval-type-call branch January 20, 2026 21:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants