diff --git a/mypy/semanal.py b/mypy/semanal.py index 5ef5223c2346..4a45032528e9 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1902,7 +1902,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="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 @@ -1926,6 +1930,7 @@ def analyze_type_param( allow_tuple_literal=type_param.kind == PARAM_SPEC_KIND, allow_unpack=type_param.kind == TYPE_VAR_TUPLE_KIND, analyzing_tvar_def=True, + prohibit_self_type="type parameter default", ) if default is None: default = PlaceholderType(None, [], context.line) @@ -1943,7 +1948,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="type parameter constraint", + ) if analyzed is None: analyzed = PlaceholderType(None, [], context.line) if has_type_vars(analyzed): diff --git a/test-data/unit/check-selftype.test b/test-data/unit/check-selftype.test index 6f73df5e05c8..947a7181078c 100644 --- a/test-data/unit/check-selftype.test +++ b/test-data/unit/check-selftype.test @@ -1494,6 +1494,23 @@ def func() -> None: class C(Self): ... # E: Self type is only allowed in annotations within class definition +[case testTypingSelfInvalidTypeParamPositions] +# https://github.com/python/mypy/issues/21960 +# flags: --python-version 3.13 +from typing import Self + +class Foo: + def meth[T: Self](self: T) -> None: ... # E: Self type cannot be used in type parameter bound + +class Bar[T: Self]: ... # E: Self type cannot be used in type parameter bound + +def func[T: (Self, int)](x: T) -> None: ... # E: Self type cannot be used in type parameter constraint + +type Alias[T: Self] = list[T] # E: Self type cannot be used in type parameter bound + +class Ok[T]: + def meth(self: Self) -> None: ... + [case testTypingSelfInvalidArgs] from typing import Self, List