diff --git a/mypy/plugins/dataclasses.py b/mypy/plugins/dataclasses.py index 211f0a8dda83..18caed8bbb8e 100644 --- a/mypy/plugins/dataclasses.py +++ b/mypy/plugins/dataclasses.py @@ -210,6 +210,7 @@ def transform(self) -> None: ) if decorator_arguments['frozen']: + self._propertize_callables(attributes, settable=False) self._freeze(attributes) else: self._propertize_callables(attributes) @@ -466,7 +467,9 @@ def _freeze(self, attributes: List[DataclassAttribute]) -> None: var._fullname = info.fullname + '.' + var.name info.names[var.name] = SymbolTableNode(MDEF, var) - def _propertize_callables(self, attributes: List[DataclassAttribute]) -> None: + def _propertize_callables(self, + attributes: List[DataclassAttribute], + settable: bool = True) -> None: """Converts all attributes with callable types to @property methods. This avoids the typechecker getting confused and thinking that @@ -480,7 +483,7 @@ def _propertize_callables(self, attributes: List[DataclassAttribute]) -> None: var = attr.to_var() var.info = info var.is_property = True - var.is_settable_property = True + var.is_settable_property = settable var._fullname = info.fullname + '.' + var.name info.names[var.name] = SymbolTableNode(MDEF, var) diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index 1773ac0eac8d..1ccf2c4d444e 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -1537,6 +1537,22 @@ A(1) A(a="foo") # E: Argument "a" to "A" has incompatible type "str"; expected "int" [builtins fixtures/dataclasses.pyi] +[case testDataclassesCallableFrozen] +# flags: --python-version 3.7 +from dataclasses import dataclass +from typing import Any, Callable +@dataclass(frozen=True) +class A: + a: Callable[..., None] + +def func() -> None: + pass + +reveal_type(A.a) # N: Revealed type is "def (*Any, **Any)" +A(a=func).a() +A(a=func).a = func # E: Property "a" defined in "A" is read-only +[builtins fixtures/dataclasses.pyi] + [case testDataclassesMultipleInheritanceWithNonDataclass] # flags: --python-version 3.10 from dataclasses import dataclass