diff --git a/mypy/semanal.py b/mypy/semanal.py index bceade1b1ac1..877903f1ec1b 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1888,7 +1888,11 @@ def analyze_type_param( ) -> TypeVarLikeExpr | None: fullname = self.qualified_name(type_param.name) if type_param.upper_bound: - upper_bound = self.anal_type(type_param.upper_bound, allow_placeholder=True) + upper_bound = self.anal_type( + type_param.upper_bound, + allow_placeholder=True, + prohibit_self_type="a type parameter bound", + ) # TODO: we should validate the upper bound is valid for a given kind. if upper_bound is None: # This and below copies special-casing for old-style type variables, that @@ -1929,7 +1933,11 @@ def analyze_type_param( values: list[Type] = [] if type_param.values: for value in type_param.values: - analyzed = self.anal_type(value, allow_placeholder=True) + analyzed = self.anal_type( + value, + allow_placeholder=True, + prohibit_self_type="a type parameter constraint", + ) if analyzed is None: analyzed = PlaceholderType(None, [], context.line) if has_type_vars(analyzed): diff --git a/test-data/unit/check-python312.test b/test-data/unit/check-python312.test index 9d612109d545..bb770a9f0917 100644 --- a/test-data/unit/check-python312.test +++ b/test-data/unit/check-python312.test @@ -1446,6 +1446,14 @@ reveal_type(F[str]().m()) # N: Revealed type is "__main__.F[builtins.str]" reveal_type(F[str]().mm(b'x')) # N: Revealed type is "tuple[__main__.F[builtins.str], builtins.bytes]" [builtins fixtures/tuple.pyi] +[case testTypingSelfInvalidLocationsTypeParams] +# flags: --python-version 3.12 +from typing import Self + +class C: + def bounded[T: Self](self: T) -> None: ... # E: Self type cannot be used in a type parameter bound + def constrained[T: (C, Self)](self: T) -> None: ... # E: Self type cannot be used in a type parameter constraint + [case testPEP695CallAlias] class C: def __init__(self, x: str) -> None: ...