Summary
(Playground: https://play.ty.dev/91b9ef76-424e-41df-8f82-761ad5a1ac54)
Suppose a class wants to store a reference to an instance, and provides a method for an instance to do so:
from typing import Self, ClassVar, final, reveal_type
@final # Same result with/without @final
class A:
_saved: ClassVar[Self]
def save(self) -> None:
type(self)._saved = self
# `ty` recognizes below that the class attribute should itself be an
# `A`, yet complains about `.save()`'s assigning to it above
# (error[invalid-assignment]: Object of type `Self@save` is not
# assignable to attribute `_saved` of type `Self@A`)
reveal_type(A._saved)
ty check (with default configs) recognizes that A._saved is an A, but flags the assignment to the attribute in A.save():
$ ty check ty-class-attr-demo.py
error[invalid-assignment]: Object of type `Self@save` is not assignable to attribute `_saved` of type `Self@A`
--> ty-class-attr-demo.py:9:9
|
8 | def save(self) -> None:
9 | type(self)._saved = self
| ^^^^^^^^^^^^^^^^^
|
info[revealed-type]: Revealed type
--> ty-class-attr-demo.py:9:9
|
14 | # (error[invalid-assignment]: Object of type `Self@save` is not
15 | # assignable to attribute `_saved` of type `Self@A`)
16 | reveal_type(A._saved)
| ^^^^^^^^ `A`
|
Found 2 diagnostics
For reference, this construction is not flagged by mypy.
Version
ty 0.0.30 (12e86b5 2026-04-14)
Summary
(Playground: https://play.ty.dev/91b9ef76-424e-41df-8f82-761ad5a1ac54)
Suppose a class wants to store a reference to an instance, and provides a method for an instance to do so:
ty check(with default configs) recognizes thatA._savedis anA, but flags the assignment to the attribute inA.save():For reference, this construction is not flagged by
mypy.Version
ty 0.0.30 (12e86b5 2026-04-14)