From 2983ed33e9323de15eb141c85a29d253d85a5195 Mon Sep 17 00:00:00 2001 From: Randolf Scholz Date: Tue, 15 Jul 2025 14:08:45 +0200 Subject: [PATCH] initial commit --- mypy/expandtype.py | 13 +++++--- test-data/unit/check-typevar-defaults.test | 36 ++++++++++++++++------ 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index d27105f48ed3..28e2a0883a3a 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -245,11 +245,16 @@ def visit_type_var(self, t: TypeVarType) -> Type: if isinstance(repl, TypeVarType) and repl.has_default(): if (tvar_id := repl.id) in self.recursive_tvar_guard: return self.recursive_tvar_guard[tvar_id] or repl + self.recursive_tvar_guard[tvar_id] = None - repl = repl.accept(self) - if isinstance(repl, TypeVarType): - repl.default = repl.default.accept(self) - self.recursive_tvar_guard[tvar_id] = repl + expanded = repl.accept(self) + + if isinstance(expanded, TypeVarType): + expanded.default = expanded.default.accept(self) + else: + repl = expanded + + self.recursive_tvar_guard[tvar_id] = expanded return repl def visit_param_spec(self, t: ParamSpecType) -> Type: diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index 22270e17787e..6d547df66d60 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -416,13 +416,31 @@ def func_c4( reveal_type(m) # N: Revealed type is "__main__.ClassC4[builtins.int, builtins.float]" [builtins fixtures/tuple.pyi] +[case testTypeVarDefaultsSwap] +from typing import TypeVar, Generic + +T = TypeVar("T") +X = TypeVar("X", default=object) +Y = TypeVar("Y", default=object) + + +class Foo(Generic[T, Y]): + def test(self) -> None: + reveal_type( Foo[Y, T]() ) # N: Revealed type is "__main__.Foo[Y`2 = builtins.object, T`1]" + + +class Bar(Generic[X, Y]): + def test(self) -> None: + reveal_type( Bar[Y, X]() ) # N: Revealed type is "__main__.Bar[Y`2 = builtins.object, Y`2 = builtins.object]" + + [case testTypeVarDefaultsClassRecursive1] # flags: --disallow-any-generics from typing import Generic, TypeVar, List T1 = TypeVar("T1", default=str) T2 = TypeVar("T2", default=T1) -T3 = TypeVar("T3", default=T2) +T3 = TypeVar("T3", default=List[T2]) T4 = TypeVar("T4", default=List[T1]) class ClassD1(Generic[T1, T2]): ... @@ -451,17 +469,17 @@ def func_d2( c: ClassD2[int, float], d: ClassD2[int, float, str], ) -> None: - reveal_type(a) # N: Revealed type is "__main__.ClassD2[builtins.str, builtins.str, builtins.str]" - reveal_type(b) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.int, builtins.int]" - reveal_type(c) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.float]" + reveal_type(a) # N: Revealed type is "__main__.ClassD2[builtins.str, builtins.str, builtins.list[builtins.str]]" + reveal_type(b) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.int, builtins.list[builtins.int]]" + reveal_type(c) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.list[builtins.float]]" reveal_type(d) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.str]" - k = ClassD2() - reveal_type(k) # N: Revealed type is "__main__.ClassD2[builtins.str, builtins.str, builtins.str]" - l = ClassD2[int]() - reveal_type(l) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.int, builtins.int]" + k = ClassD2() # E: Need type annotation for "k" + reveal_type(k) # N: Revealed type is "__main__.ClassD2[builtins.str, builtins.str, builtins.list[Any]]" + l = ClassD2[int]() # E: Need type annotation for "l" + reveal_type(l) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.int, builtins.list[Any]]" m = ClassD2[int, float]() - reveal_type(m) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.float]" + reveal_type(m) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.list[builtins.float]]" n = ClassD2[int, float, str]() reveal_type(n) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.str]"