basedpyright icon indicating copy to clipboard operation
basedpyright copied to clipboard

`Self` should not be allowed in a contravariant position

Open DetachHead opened this issue 4 months ago • 2 comments

Description

Code sample in basedpyright playground

from typing import Self, reveal_type

class Foo:
    instance: Self

class Bar(Foo): ...

bar = Bar()

def fn(value: Foo):
    foo: Foo = value
    foo.instance = Foo()

fn(bar)

reveal_type(bar.instance) # Bar, but Foo at runtime

not sure how we'd fix this. it looks like this means when Self is used in an input position the class can no longer safely be subtyped? need to think about this some more

think this is related to #1566

DetachHead avatar Oct 16 '25 11:10 DetachHead

oh, i know

class A:
    def f(self): ...

class B(A):
    x = 1
    def f(self):
        self.x

x: type[A] = cast(type[A], B)
x.f(A())

KotlinIsland avatar Oct 16 '25 11:10 KotlinIsland

i think the solution here is to ban Self from being used in a contravariant position

an exception would obviously need to be made for the self parameter on methods, as long as we implement a rule to ban calling it on the class (#1566)

DetachHead avatar Oct 16 '25 11:10 DetachHead