generics on frozen dataclasses should be inferred as covariant instead of invariant
Description
https://github.com/microsoft/pyright/issues/9226
Note: dataclasses now have a __replace__ method, so if you just do this naive generation:
@dataclass(frozen=True)
class Fruit[C]:
name: str
allowed_colors: Collection[C]
# *pretend that this is synthesized*
def __replace__(self, *, name: str = ..., allowed_colors: Collection[C] = ...) -> Self:
...
Then Fruit has to be invariant. So I think you will need to make it generic:
@dataclass(frozen=True)
class Fruit[C]:
name: str
allowed_colors: Collection[C]
# *pretend that this is synthesized*
def __replace__[C2=C](self, *, name: str = ..., allowed_colors: Collection[C2] = ...) -> Fruit[C2]:
...
Well... this is not allowed because Type parameter "C2" has a default type that refers to one or more type variables that are out of scope. So maybe it needs to be an overload?
@dataclass(frozen=True)
class Fruit[C]:
name: str
allowed_colors: Collection[C]
# *pretend that this is synthesized*
@overload
def __replace__(self, *, name: str = ...) -> Fruit[C]: ...
@overload
def __replace__[C2](self, *, name: str = ..., allowed_colors: Collection[C2]) -> Fruit[C2]: ...
if there are N type variables, should this synthesize 2**N overloads?
Also see: https://github.com/python/mypy/issues/19694
relevant: #171
@DetachHead I think this should be un-closed, because @dataclasses.dataclass-annotated classes still suffer from this issue
oh true