Skip to content

Commit 4c8e60c

Browse files
committed
[PEP 695] Detect invalid number of constrained types
At least two are required, according do PEP 695. Work on #15238.
1 parent 8dd268f commit 4c8e60c

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

mypy/fastparse.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -1185,8 +1185,12 @@ def translate_type_params(self, type_params: list[Any]) -> list[TypeParam]:
11851185
explicit_type_params.append(TypeParam(p.name, TYPE_VAR_TUPLE_KIND, None, []))
11861186
else:
11871187
if isinstance(p.bound, ast3.Tuple):
1188-
conv = TypeConverter(self.errors, line=p.lineno)
1189-
values = [conv.visit(t) for t in p.bound.elts]
1188+
if len(p.bound.elts) < 2:
1189+
self.fail(message_registry.TYPE_VAR_TOO_FEW_CONSTRAINED_TYPES,
1190+
p.lineno, p.col_offset, blocker=False)
1191+
else:
1192+
conv = TypeConverter(self.errors, line=p.lineno)
1193+
values = [conv.visit(t) for t in p.bound.elts]
11901194
elif p.bound is not None:
11911195
bound = TypeConverter(self.errors, line=p.lineno).visit(p.bound)
11921196
explicit_type_params.append(TypeParam(p.name, TYPE_VAR_KIND, bound, values))

mypy/message_registry.py

+3
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,6 @@ def with_additional_msg(self, info: str) -> ErrorMessage:
330330
NARROWED_TYPE_NOT_SUBTYPE: Final = ErrorMessage(
331331
"Narrowed type {} is not a subtype of input type {}", codes.NARROWED_TYPE_NOT_SUBTYPE
332332
)
333+
TYPE_VAR_TOO_FEW_CONSTRAINED_TYPES: Final = ErrorMessage(
334+
"Type variable must have at least two constrained types", codes.MISC
335+
)

test-data/unit/check-python312.test

+10
Original file line numberDiff line numberDiff line change
@@ -1494,3 +1494,13 @@ reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]"
14941494
# flags: --enable-incomplete-feature=NewGenericSyntax
14951495
def f[T](x: foobar, y: T) -> T: ... # E: Name "foobar" is not defined
14961496
reveal_type(f) # N: Revealed type is "def [T] (x: Any, y: T`-1) -> T`-1"
1497+
1498+
[case testPEP695WrongNumberOfConstrainedTypes]
1499+
# flags: --enable-incomplete-feature=NewGenericSyntax
1500+
type A[T: ()] = list[T] # E: Type variable must have at least two constrained types
1501+
a: A[int]
1502+
reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]"
1503+
1504+
type B[T: (int,)] = list[T] # E: Type variable must have at least two constrained types
1505+
b: B[str]
1506+
reveal_type(b) # N: Revealed type is "builtins.list[builtins.str]"

0 commit comments

Comments
 (0)