In my code base I have many declarations like this: from typing import Protocol, override from dataclasses import dataclass # Definition of protocols (usually in a separate file) @dataclass class Data(Protocol): val: int = 1 class Programm(Protocol): def update(self, data: Data) -> int: ... # Concrete implementation of the protocols: @dataclass class DataA(Data): val_concrete: int = 2 class ProgrammA(Programm): @override def update(self, data: DataA) -> int: return data.val_concrete + data.val I was confident that this is the right way to use protocols. Maybe I am mistaken. When I turn on pyright (in fact I use basedpyright, but I should be the same), it marks ProgrammA.update() and complains: [reportIncompatibleMethodOverride]: Method "update" overrides class "Programm" in an incompatible manner Am I doing something wrong? I can get around this using a redundant generic. But I think this is unnecessary and in some way just wrong. If my approach is correct, can I do something to clarify things in a way, pyright understands? Continue reading...