Skip to content

Commit 5f8e69c

Browse files
committed
Check function TypeVar defaults
1 parent 7ab29a2 commit 5f8e69c

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

mypy/checker.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,7 @@ def check_func_def(
11591159
) -> None:
11601160
"""Type check a function definition."""
11611161
# Expand type variables with value restrictions to ordinary types.
1162+
self.check_typevar_defaults(typ.variables)
11621163
expanded = self.expand_typevars(defn, typ)
11631164
original_typ = typ
11641165
for item, typ in expanded:
@@ -2548,7 +2549,7 @@ def check_init_subclass(self, defn: ClassDef) -> None:
25482549
# all other bases have already been checked.
25492550
break
25502551

2551-
def check_typevar_defaults(self, tvars: list[TypeVarLikeType]) -> None:
2552+
def check_typevar_defaults(self, tvars: Sequence[TypeVarLikeType]) -> None:
25522553
for tv in tvars:
25532554
if not (isinstance(tv, TypeVarType) and tv.has_default()):
25542555
continue

test-data/unit/check-python313.test

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,34 @@ class ClassTs3[*Ts = tuple[int]]: ... # E: The default argument to TypeVarTuple
6464
[builtins fixtures/tuple.pyi]
6565

6666
[case testPEP695TypeParameterDefaultInvalid2]
67+
from typing import overload
68+
def f1[T = 2]() -> None: ... # E: TypeVar "default" must be a type
69+
def f2[T = [int]]() -> None: ... # E: Bracketed expression "[...]" is not valid as a type \
70+
# N: Did you mean "List[...]"? \
71+
# E: TypeVar "default" must be a type
72+
def f3[T: str = int](x: T) -> T: ... # E: TypeVar default must be a subtype of the bound type
73+
def f4[T: list[str] = list[int]](x: T) -> T: ... # E: TypeVar default must be a subtype of the bound type
74+
def f5[T: (int, str) = bytes](x: T) -> T: ... # E: TypeVar default must be one of the constraint types
75+
def f6[T: (int, str) = int | str](x: T) -> T: ... # E: TypeVar default must be one of the constraint types
76+
def f7[T: (float, str) = int](x: T) -> T: ... # E: TypeVar default must be one of the constraint types
77+
def f8[T: str = int]() -> None: ... # TODO check unused TypeVars
78+
@overload
79+
def f9[T: str = int](x: T) -> T: ... # E: TypeVar default must be a subtype of the bound type
80+
@overload
81+
def f9[T: (int, str) = bytes](x: T) -> T: ... # E: TypeVar default must be one of the constraint types
82+
def f9() -> None: ... # type: ignore[misc]
83+
84+
def g1[**P = int]() -> None: ... # E: The default argument to ParamSpec must be a list expression, ellipsis, or a ParamSpec
85+
def g2[**P = 2]() -> None: ... # E: The default argument to ParamSpec must be a list expression, ellipsis, or a ParamSpec
86+
def g3[**P = (2, int)]() -> None: ... # E: The default argument to ParamSpec must be a list expression, ellipsis, or a ParamSpec
87+
def g4[**P = [2, int]]() -> None: ... # E: Argument 0 of ParamSpec default must be a type
88+
89+
def h1[*Ts = 2]() -> None: ... # E: The default argument to TypeVarTuple must be an Unpacked tuple
90+
def h2[*Ts = int]() -> None: ... # E: The default argument to TypeVarTuple must be an Unpacked tuple
91+
def h3[*Ts = tuple[int]]() -> None: ... # E: The default argument to TypeVarTuple must be an Unpacked tuple
92+
[builtins fixtures/tuple.pyi]
93+
94+
[case testPEP695TypeParameterDefaultInvalid3]
6795
from typing import Callable
6896

6997
type TA1[T: str = 1] = list[T] # E: TypeVar "default" must be a type

0 commit comments

Comments
 (0)