From 1f9317f593dc41a2805a3093e2e1890665485e76 Mon Sep 17 00:00:00 2001 From: bzoracler <50305397+bzoracler@users.noreply.github.com> Date: Thu, 19 Dec 2024 19:01:21 +1300 Subject: [PATCH] fix: fail check if not enough or too many types provided to `TypeAliasType` (#18308) Fixes #18307 by failing a type alias call check if the number of positional arguments isn't exactly 2 (one for the type name as a literal string, one for the target type to alias). Before: ```python from typing_extensions import TypeAliasType T1 = TypeAliasType("T1", int, str) # Silently passes and uses `int` as the target type, should be an error T2 = TypeAliasType("T2") # Crashes ``` After: ```python T1 = TypeAliasType("T1", int, str) # E: Too many positional arguments for "TypeAliasType" T2 = TypeAliasType("T2") # E: Missing positional argument "value" in call to "TypeAliasType" ``` The error messages above are propagated from a check with the [`TypeAliasType` constructor definition from the stubs](https://github.com/python/typeshed/blob/bd728fbfae18395c37d9fd020e31b1d4f30c6136/stdlib/typing.pyi#L1041-L1044), so no further special-casing is necessary: ```python class TypeAliasType: def __init__( self, name: str, value: Any, *, type_params: tuple[TypeVar | ParamSpec | TypeVarTuple, ...] = () ) -> None: ... ``` --- mypy/semanal.py | 6 +++++- test-data/unit/check-type-aliases.test | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index e90ab9f160e0a..42803727a9588 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -4157,8 +4157,12 @@ def check_type_alias_type_call(self, rvalue: Expression, *, name: str) -> TypeGu names.append("typing.TypeAliasType") if not refers_to_fullname(rvalue.callee, tuple(names)): return False + if not self.check_typevarlike_name(rvalue, name, rvalue): + return False + if rvalue.arg_kinds.count(ARG_POS) != 2: + return False - return self.check_typevarlike_name(rvalue, name, rvalue) + return True def analyze_type_alias_type_params( self, rvalue: CallExpr diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index c7b9694a91887..4073836dd973b 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1105,6 +1105,10 @@ t1: T1 # E: Variable "__main__.T1" is not valid as a type \ T3 = TypeAliasType("T3", -1) # E: Invalid type: try using Literal[-1] instead? t3: T3 reveal_type(t3) # N: Revealed type is "Any" + +T4 = TypeAliasType("T4") # E: Missing positional argument "value" in call to "TypeAliasType" +T5 = TypeAliasType("T5", int, str) # E: Too many positional arguments for "TypeAliasType" \ + # E: Argument 3 to "TypeAliasType" has incompatible type "Type[str]"; expected "Tuple[Union[TypeVar?, ParamSpec?, TypeVarTuple?], ...]" [builtins fixtures/tuple.pyi] [typing fixtures/typing-full.pyi]