TLDR: I’m trying to navigate the mypy codebase and work out where/how Self
is handled.
Given the code
from typing import Self, reveal_type
class C:
def foo(self: C) -> None:
pass
def bar(self) -> None:
pass
def baz(self: Self) -> None:
pass
reveal_type(C.foo)
reveal_type(C.bar)
reveal_type(C.baz)
mypy shows
main.py:10: note: Revealed type is "def (self: __main__.C)"
main.py:11: note: Revealed type is "def (self: __main__.C)"
main.py:12: note: Revealed type is "def [Self <: __main__.C] (self: Self`551)"
mypy’s syntax for generic type parameters is the square brackets, so looks like its treating the Self
type as a shorthand for a generic type with an upper bound for the enclosing class, and unannotated functions as implicitly of the enclosing class.
I’m trying to work out where the 2 cases are handled in the mypy codebase and trying to work out how it might be possible to switch mypy to infer a generic Self
by default but mypy is a tricky code base to navigate due to all the visitor calls. Any pointers would be appreciated!