This MRE illustrates my problem: from dataclasses import dataclass from typing import Protocol class Child(Protocol): val: float class Parent(Protocol): sub: Child @dataclass class Child1(Child): val: float @dataclass class Parent1(Parent): sub: Child1 # <- Pyright complains here To my eyes, the Parent1-class appears as a valid implementation of the Parent-protocol. I plan to use this a lot. mypy approves this while pyright does not. The latter complains: "sub" overrides symbol of same name in class "Parent" Variable is mutable so its type is invariant Override type "Child1" is not the same as base type "Child" (reportIncompatibleVariableOverride) I do not understand. What has mutability to do with it? Playing around with frozen=True does not change anything, And why does mypy comply? Can I do something about it? Adjust the code or pacify pyright somehow? Continue reading...