From 4196f0f625e01e7230a8dfc41e81ba5984c65233 Mon Sep 17 00:00:00 2001 From: iliyasone Date: Mon, 18 May 2026 22:22:55 +0300 Subject: [PATCH 1/2] Fix eval_call_with_types vararg annotations eval_call_with_types accepts individual type objects as positional and keyword arguments, but its annotation described each *arg as a tuple and each **kwarg value as a dict. That made mypy reject valid calls such as eval_call_with_types(func, User) and encouraged tuple-wrapping that does not match the runtime binding contract. Update the public signature to annotate each supplied type object directly and add a regression test that is checked by the mypy test harness for both positional and keyword type objects. Validation: uv run pytest; uv run ruff check .; uv run ruff format --check .; uv run mypy --config-file pyproject.toml typemap --- tests/test_eval_call_with_types_signature.py | 15 +++++++++++++++ typemap/type_eval/_eval_call.py | 6 +++--- 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 tests/test_eval_call_with_types_signature.py diff --git a/tests/test_eval_call_with_types_signature.py b/tests/test_eval_call_with_types_signature.py new file mode 100644 index 0000000..ff798eb --- /dev/null +++ b/tests/test_eval_call_with_types_signature.py @@ -0,0 +1,15 @@ +from typemap.type_eval import eval_call_with_types + + +def test_eval_call_with_types_accepts_positional_type_objects(): + def func[T](value: T) -> T: + raise NotImplementedError + + assert eval_call_with_types(func, int) is int + + +def test_eval_call_with_types_accepts_keyword_type_objects(): + def func[T](*, value: T) -> T: + raise NotImplementedError + + assert eval_call_with_types(func, value=str) is str diff --git a/typemap/type_eval/_eval_call.py b/typemap/type_eval/_eval_call.py index 570041d..f950386 100644 --- a/typemap/type_eval/_eval_call.py +++ b/typemap/type_eval/_eval_call.py @@ -144,9 +144,9 @@ def _update_bound_typevar( def eval_call_with_types( - func: types.FunctionType | typing.Callable, - *arg_types: tuple[RtType, ...], - **kwarg_types: dict[str, RtType], + func: types.FunctionType | typing.Callable[..., Any], + *arg_types: RtType, + **kwarg_types: RtType, ) -> RtType: if isinstance(func, types.FunctionType): vars: dict[str, Any] = _get_bound_type_args( From db070467b388c8257584012aaf49664275924e41 Mon Sep 17 00:00:00 2001 From: iliyasone Date: Mon, 18 May 2026 22:40:37 +0300 Subject: [PATCH 2/2] Type-check eval_call_with_types signature tests The eval_call_with_types regression tests need typed pytest function bodies so mypy checks the calls inside them. Without return annotations, mypy skips those bodies under the current config, so reverting the public signature is not caught by the mypy harness. Annotate the regression test functions with -> None. Verified that the old tuple/dict vararg signature now fails both direct mypy on the test file and the pytest-driven mypy harness, while the fixed signature passes. Validation: uv run pytest; uv run ruff check .; uv run ruff format --check .; uv run mypy --config-file pyproject.toml tests/test_eval_call_with_types_signature.py --- tests/test_eval_call_with_types_signature.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_eval_call_with_types_signature.py b/tests/test_eval_call_with_types_signature.py index ff798eb..7c7e5d3 100644 --- a/tests/test_eval_call_with_types_signature.py +++ b/tests/test_eval_call_with_types_signature.py @@ -1,14 +1,14 @@ from typemap.type_eval import eval_call_with_types -def test_eval_call_with_types_accepts_positional_type_objects(): +def test_eval_call_with_types_accepts_positional_type_objects() -> None: def func[T](value: T) -> T: raise NotImplementedError assert eval_call_with_types(func, int) is int -def test_eval_call_with_types_accepts_keyword_type_objects(): +def test_eval_call_with_types_accepts_keyword_type_objects() -> None: def func[T](*, value: T) -> T: raise NotImplementedError