Describe the bug
When a TypeVar is bound to a Protocol that uses Self as a parameter type (contravariant position), pyright incorrectly accepts a union type as satisfying the bound.
Code or Screenshots
from typing import Protocol, Self, final
class SelfSerializable(Protocol):
@classmethod
def serialize(cls, value: Self) -> bytes: ...
@final
class Foo:
def __init__(self, x: int) -> None:
self.x = x
@classmethod
def serialize(cls, value: Self) -> bytes:
return value.x.to_bytes(4)
@final
class Bar:
def __init__(self, name: str) -> None:
self.name = name
@classmethod
def serialize(cls, value: Self) -> bytes:
return value.name.encode()
def serialize_other[T: SelfSerializable](template: T, value: T) -> bytes:
return type(template).serialize(value)
_ = serialize_other(Bar("name"), Foo(42))
0 diagnostics, runtime crash.
Writing def serialize[T](cls: type[T], value: T) -> bytes: ... in SelfSerializable makes no difference.
VS Code extension or command-line
1.1.408, through cmdline.
Describe the bug
When a TypeVar is bound to a Protocol that uses Self as a parameter type (contravariant position), pyright incorrectly accepts a union type as satisfying the bound.
Code or Screenshots
0 diagnostics, runtime crash.
Writing
def serialize[T](cls: type[T], value: T) -> bytes: ...inSelfSerializablemakes no difference.VS Code extension or command-line
1.1.408, through cmdline.