diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 125cba219dc5..d5c8de14cea4 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -2150,6 +2150,9 @@ def instantiate_type_alias( and act_len == 0 and not (empty_tuple_index and node.tvar_tuple_index is not None) ): + if node.python_3_12_type_alias: + # Pass original type variables to preserve genericity in the alias reference + return TypeAliasType(node, list(node.alias_tvars), line=ctx.line, column=ctx.column) # Interpret bare Alias same as normal generic, i.e., Alias[Any, Any, ...] return set_any_tvars( node, @@ -2167,7 +2170,6 @@ def instantiate_type_alias( # Note: this is the only case where we use an eager expansion. See more info about # no_args aliases like L = List in the docstring for TypeAlias class. return Instance(node.target.type, [], line=ctx.line, column=ctx.column) - return TypeAliasType(node, [], line=ctx.line, column=ctx.column) if ( max_tv_count == 0 and act_len > 0 diff --git a/pytest b/pytest new file mode 100644 index 000000000000..ef5571d4af18 --- /dev/null +++ b/pytest @@ -0,0 +1 @@ +PATH=C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files (x86)\PDFtk\bin\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\160\Tools\Binn\;C:\Program Files\Microsoft SQL Server\160\Tools\Binn\;C:\Program Files\Microsoft SQL Server\160\DTS\Binn\;C:\Program Files\dotnet\;E:\flutter\bin;C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\bin;C:\ProgramData\chocolatey\bin;E:\Git\cmd;C:\Program Files\GTK3-Runtime Win64\bin;C:\Users\Admin\AppData\Local\nvm;C:\nvm4w\nodejs;C:\Users\Admin\AppData\Local\Microsoft\WindowsApps;C:\Users\Admin\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\Admin\.dotnet\tools;E:\python\;E:\python\Scripts\;E:\flutter\bin;C:\Users\Admin\AppData\Local\Android\Sdk\platform-tools;C:\Users\Admin\AppData\Local\Android\Sdk\cmdline-tools\latest\bin;E:\PyCharm 2025.2.2\bin;E:\pycharm\PyCharm Community Edition 2024.3.5\bin;;C:\Users\Admin\AppData\Roaming\npm;C:\Users\Admin\AppData\Local\nvm;C:\nvm4w\nodejs mypy/test/testcheck.py -k testPep695GenericTypeAliasReassignment\PATH.txt diff --git a/test-data/unit/check-python312.test b/test-data/unit/check-python312.test index a67ed4abcffa..5ccc2d82db05 100644 --- a/test-data/unit/check-python312.test +++ b/test-data/unit/check-python312.test @@ -1479,7 +1479,7 @@ class D(C): pass type A[T: C] = list[T] a1: A -reveal_type(a1) # N: Revealed type is "builtins.list[Any]" +reveal_type(a1) # N: Revealed type is "builtins.list[T`1]" a2: A[Any] a3: A[C] a4: A[D] @@ -1491,7 +1491,7 @@ x2 = cast(A[None], a1) # E: Type argument "None" of "A" must be a subtype of "C type A2[T: (int, C)] = list[T] b1: A2 -reveal_type(b1) # N: Revealed type is "builtins.list[Any]" +reveal_type(b1) # N: Revealed type is "builtins.list[T`1]" b2: A2[Any] b3: A2[int] b4: A2[C] @@ -2237,3 +2237,24 @@ class D[*Ts](Generic[Unpack[Us]]): # E: Generic[...] base class is redundant \ # E: Can only use one type var tuple in a class def pass [builtins fixtures/tuple.pyi] + +[case testPep695GenericTypeAliasReassignmentAndUsage] +import types +from typing import reveal_type + +type A[T] = list[T] | str + +# 1. Assignment (The Fix) +B = A +reveal_type(B) # N: Revealed type is "types.UnionType[builtins.list[T`1], builtins.str]" + +# 2. Usage (The Regression Check) +def foo(x: B[int]) -> None: # E: Bad number of arguments for type alias, expected 0, given 1 + reveal_type(x) # N: Revealed type is "Union[builtins.list[T`1], builtins.str]" + +[file types.pyi] +class UnionType: ... +class GenericAlias: ... + +[builtins fixtures/list.pyi] +[typing fixtures/typing-full.pyi] diff --git a/test-data/unit/check-python313.test b/test-data/unit/check-python313.test index 117d20ceaf0b..070668a6637d 100644 --- a/test-data/unit/check-python313.test +++ b/test-data/unit/check-python313.test @@ -215,7 +215,7 @@ def func_a1( c: TA1[float, float], d: TA1[float, float, float], # E: Bad number of arguments for type alias, expected between 0 and 2, given 3 ) -> None: - reveal_type(a) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" + reveal_type(a) # N: Revealed type is "builtins.dict[T2`1 = builtins.int, T3`2 = builtins.str]" reveal_type(b) # N: Revealed type is "builtins.dict[builtins.float, builtins.str]" reveal_type(c) # N: Revealed type is "builtins.dict[builtins.float, builtins.float]" reveal_type(d) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" @@ -234,7 +234,7 @@ def func_b1( c: TB1[[float], [float]], d: TB1[[float], [float], [float]], # E: Bad number of arguments for type alias, expected between 0 and 2, given 3 ) -> None: - reveal_type(a) # N: Revealed type is "__main__.ClassB1[[builtins.int, builtins.str], [*Any, **Any]]" + reveal_type(a) # N: Revealed type is "__main__.ClassB1[P2`1 = [builtins.int, builtins.str], P3`2 = ...]" reveal_type(b) # N: Revealed type is "__main__.ClassB1[[builtins.float], [*Any, **Any]]" reveal_type(c) # N: Revealed type is "__main__.ClassB1[[builtins.float], [builtins.float]]" reveal_type(d) # N: Revealed type is "__main__.ClassB1[[builtins.int, builtins.str], [*Any, **Any]]"