From a31e02e4c7668a848d31418ae36625f7ce0a208e Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Fri, 23 Sep 2022 15:50:04 -0700 Subject: [PATCH 1/3] Treat __dataclass_fields__ as ClassVar --- mypy/plugins/dataclasses.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mypy/plugins/dataclasses.py b/mypy/plugins/dataclasses.py index 89a21871c373..26bc8ae80fdb 100644 --- a/mypy/plugins/dataclasses.py +++ b/mypy/plugins/dataclasses.py @@ -593,6 +593,7 @@ def _add_dataclass_fields_magic_attribute(self) -> None: var = Var(name=attr_name, type=attr_type) var.info = self._ctx.cls.info var._fullname = self._ctx.cls.info.fullname + "." + attr_name + var.is_classvar = True self._ctx.cls.info.names[attr_name] = SymbolTableNode( kind=MDEF, node=var, plugin_generated=True ) From 6b4717f2c904babf3f922b8c8792d32008d2ea61 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Fri, 23 Sep 2022 16:36:05 -0700 Subject: [PATCH 2/3] fix existing tests --- test-data/unit/check-dataclasses.test | 4 ++-- test-data/unit/fine-grained.test | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index b821aefe8f7c..d19b69d99945 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -1819,10 +1819,10 @@ c.x # E: "C" has no attribute "x" [case testDataclassCheckTypeVarBounds] # flags: --python-version 3.7 from dataclasses import dataclass -from typing import Protocol, Dict, TypeVar, Generic +from typing import ClassVar, Protocol, Dict, TypeVar, Generic class DataclassProtocol(Protocol): - __dataclass_fields__: Dict + __dataclass_fields__: ClassVar[Dict] T = TypeVar("T", bound=DataclassProtocol) diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index 9d8857301425..971da91d7a40 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -9795,11 +9795,11 @@ class ExampleClass(Generic[T]): [case testDataclassCheckTypeVarBoundsInReprocess] # flags: --python-version 3.7 from dataclasses import dataclass -from typing import Protocol, Dict, TypeVar, Generic +from typing import ClassVar, Protocol, Dict, TypeVar, Generic from m import x class DataclassProtocol(Protocol): - __dataclass_fields__: Dict + __dataclass_fields__: ClassVar[Dict] T = TypeVar("T", bound=DataclassProtocol) From 1e41fe7d128ecea870151e67181babc408021ffa Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Sat, 24 Sep 2022 16:03:16 -0700 Subject: [PATCH 3/3] add a test --- test-data/unit/check-dataclasses.test | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index d19b69d99945..e4f2bfb44160 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -1896,3 +1896,20 @@ FirstClass().FIRST_CONST = 42 # E: Cannot assign to final attribute "FIRST_CONS reveal_type(SecondClass().SECOND_CONST) # N: Revealed type is "Literal[3]?" SecondClass().SECOND_CONST = 42 # E: Cannot assign to final attribute "SECOND_CONST" [builtins fixtures/dataclasses.pyi] + +[case testDataclassFieldsProtocol] +# flags: --python-version 3.9 +from dataclasses import dataclass +from typing import Any, Protocol + +class ConfigProtocol(Protocol): + __dataclass_fields__: dict[str, Any] + +def takes_cp(cp: ConfigProtocol): ... + +@dataclass +class MyDataclass: + x: int = 3 + +takes_cp(MyDataclass) +[builtins fixtures/dataclasses.pyi]