From 9d7a04277ebb5edcfe649977fb5bb45ac91573f6 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Wed, 18 Sep 2024 14:42:25 +0100 Subject: [PATCH] [PEP 695] Fix covariance of frozen dataclasses (#17783) Fix this conformance test: ``` @dataclass(frozen=True) class ShouldBeCovariant4[T]: x: T vo4_1: ShouldBeCovariant4[float] = ShouldBeCovariant4[int](1) # OK vo4_2: ShouldBeCovariant4[int] = ShouldBeCovariant4[float](1) # E ``` Link: https://github.com/python/typing/blob/main/conformance/tests/generics_variance_inference.py#L66 --- mypy/subtypes.py | 3 ++- test-data/unit/check-python312.test | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 6e2366c4e0df..5c4471cc5b62 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -2004,7 +2004,8 @@ def infer_variance(info: TypeInfo, i: int) -> bool: tvar = info.defn.type_vars[i] self_type = fill_typevars(info) for member in all_non_object_members(info): - if member in ("__init__", "__new__"): + # __mypy-replace is an implementation detail of the dataclass plugin + if member in ("__init__", "__new__", "__mypy-replace"): continue if isinstance(self_type, TupleType): diff --git a/test-data/unit/check-python312.test b/test-data/unit/check-python312.test index 9dc52d2c07b0..d0a39f7e56a6 100644 --- a/test-data/unit/check-python312.test +++ b/test-data/unit/check-python312.test @@ -249,6 +249,25 @@ if int(): if int(): f = e +[case testPEP695InferVarianceInFrozenDataclass] +# flags: --enable-incomplete-feature=NewGenericSyntax +from dataclasses import dataclass + +@dataclass(frozen=True) +class Covariant[T]: + x: T + +cov1: Covariant[float] = Covariant[int](1) +cov2: Covariant[int] = Covariant[float](1) # E: Incompatible types in assignment (expression has type "Covariant[float]", variable has type "Covariant[int]") + +@dataclass(frozen=True) +class Invariant[T]: + x: list[T] + +inv1: Invariant[float] = Invariant[int]([1]) # E: Incompatible types in assignment (expression has type "Invariant[int]", variable has type "Invariant[float]") +inv2: Invariant[int] = Invariant[float]([1]) # E: Incompatible types in assignment (expression has type "Invariant[float]", variable has type "Invariant[int]") +[builtins fixtures/tuple.pyi] + [case testPEP695InferVarianceCalculateOnDemand] # flags: --enable-incomplete-feature=NewGenericSyntax