Skip to content

Instance method cannot assign self to classvar typed as an instance #3274

@TTsangSC

Description

@TTsangSC

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)

Metadata

Metadata

Assignees

Labels

genericsBugs or features relating to ty's generics implementation

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions