diff --git a/mypy/checker.py b/mypy/checker.py index 596564c98a40..442fe47fc80b 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3698,6 +3698,9 @@ def check_assignment_to_slots(self, lvalue: Lvalue) -> None: return inst = get_proper_type(self.expr_checker.accept(lvalue.expr)) + if isinstance(inst, TypeVarType) and inst.id.is_self(): + # Unwrap self type + inst = get_proper_type(inst.upper_bound) if not isinstance(inst, Instance): return if inst.type.slots is None: diff --git a/test-data/unit/check-slots.test b/test-data/unit/check-slots.test index b7ce5e596101..79467199c872 100644 --- a/test-data/unit/check-slots.test +++ b/test-data/unit/check-slots.test @@ -521,3 +521,19 @@ x = X() X.a # E: "a" in __slots__ conflicts with class variable access x.a [builtins fixtures/tuple.pyi] + +[case testSlotsOnSelfType] +from typing_extensions import Self + +class X: + __slots__ = ("foo",) + foo: int + + def method1(self: Self) -> Self: + self.bar = 0 # E: Trying to assign name "bar" that is not in "__slots__" of type "__main__.X" + return self + + def method2(self) -> Self: + self.bar = 0 # E: Trying to assign name "bar" that is not in "__slots__" of type "__main__.X" + return self +[builtins fixtures/tuple.pyi]