FYI there is also
@dataclass(frozen=True)
this tends to be enough for my usecases. you can still circumvent (and sometimes have to in dataclass post_init) with object.__setattr__.