Skip to content

Commit

Permalink
[PEP 695] Detect invalid number of constrained types
Browse files Browse the repository at this point in the history
At least two are required, according do PEP 695.

Work on #15238.
  • Loading branch information
JukkaL committed Jun 6, 2024
1 parent 8dd268f commit 4c8e60c
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 2 deletions.
8 changes: 6 additions & 2 deletions mypy/fastparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1185,8 +1185,12 @@ def translate_type_params(self, type_params: list[Any]) -> list[TypeParam]:
explicit_type_params.append(TypeParam(p.name, TYPE_VAR_TUPLE_KIND, None, []))
else:
if isinstance(p.bound, ast3.Tuple):
conv = TypeConverter(self.errors, line=p.lineno)
values = [conv.visit(t) for t in p.bound.elts]
if len(p.bound.elts) < 2:
self.fail(message_registry.TYPE_VAR_TOO_FEW_CONSTRAINED_TYPES,
p.lineno, p.col_offset, blocker=False)
else:
conv = TypeConverter(self.errors, line=p.lineno)
values = [conv.visit(t) for t in p.bound.elts]
elif p.bound is not None:
bound = TypeConverter(self.errors, line=p.lineno).visit(p.bound)
explicit_type_params.append(TypeParam(p.name, TYPE_VAR_KIND, bound, values))
Expand Down
3 changes: 3 additions & 0 deletions mypy/message_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,6 @@ def with_additional_msg(self, info: str) -> ErrorMessage:
NARROWED_TYPE_NOT_SUBTYPE: Final = ErrorMessage(
"Narrowed type {} is not a subtype of input type {}", codes.NARROWED_TYPE_NOT_SUBTYPE
)
TYPE_VAR_TOO_FEW_CONSTRAINED_TYPES: Final = ErrorMessage(
"Type variable must have at least two constrained types", codes.MISC
)
10 changes: 10 additions & 0 deletions test-data/unit/check-python312.test
Original file line number Diff line number Diff line change
Expand Up @@ -1494,3 +1494,13 @@ reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]"
# flags: --enable-incomplete-feature=NewGenericSyntax
def f[T](x: foobar, y: T) -> T: ... # E: Name "foobar" is not defined
reveal_type(f) # N: Revealed type is "def [T] (x: Any, y: T`-1) -> T`-1"

[case testPEP695WrongNumberOfConstrainedTypes]
# flags: --enable-incomplete-feature=NewGenericSyntax
type A[T: ()] = list[T] # E: Type variable must have at least two constrained types
a: A[int]
reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]"

type B[T: (int,)] = list[T] # E: Type variable must have at least two constrained types
b: B[str]
reveal_type(b) # N: Revealed type is "builtins.list[builtins.str]"

0 comments on commit 4c8e60c

Please sign in to comment.