Skip to content

Commit ac921ae

Browse files
authored
Fix "not callable" issue for @dataclass(frozen=True) with Final attr (#18572)
Closes #18567 We should allow inferenced `a: Final = 1`
1 parent 75a4bc4 commit ac921ae

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

mypy/plugins/dataclasses.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,8 @@ def _freeze(self, attributes: list[DataclassAttribute]) -> None:
768768
if sym_node is not None:
769769
var = sym_node.node
770770
if isinstance(var, Var):
771+
if var.is_final:
772+
continue # do not turn `Final` attrs to `@property`
771773
var.is_property = True
772774
else:
773775
var = attr.to_var(info)

test-data/unit/check-dataclasses.test

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2553,3 +2553,26 @@ class X(metaclass=DCMeta):
25532553
class Y(X):
25542554
a: int # E: Covariant override of a mutable attribute (base class "X" defined the type as "Optional[int]", expression has type "int")
25552555
[builtins fixtures/tuple.pyi]
2556+
2557+
2558+
[case testFrozenWithFinal]
2559+
from dataclasses import dataclass
2560+
from typing import Final
2561+
2562+
@dataclass(frozen=True)
2563+
class My:
2564+
a: Final = 1
2565+
b: Final[int] = 2
2566+
2567+
reveal_type(My.a) # N: Revealed type is "Literal[1]?"
2568+
reveal_type(My.b) # N: Revealed type is "builtins.int"
2569+
My.a = 1 # E: Cannot assign to final attribute "a"
2570+
My.b = 2 # E: Cannot assign to final attribute "b"
2571+
2572+
m = My()
2573+
reveal_type(m.a) # N: Revealed type is "Literal[1]?"
2574+
reveal_type(m.b) # N: Revealed type is "builtins.int"
2575+
2576+
m.a = 1 # E: Cannot assign to final attribute "a"
2577+
m.b = 2 # E: Cannot assign to final attribute "b"
2578+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)