Skip to content

Commit 9dad464

Browse files
authored
Do not include non-init fields in the synthesized __replace__ method for dataclasses (#18221)
At runtime, non init fields are not allowed when using replace. See [the source code](https://github.com/python/cpython/blob/1bc4f076d193ad157bdc69a1d62685a15f95113f/Lib/dataclasses.py#L1671-L1676) of the CPython implementation.
1 parent 3268a7a commit 9dad464

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

mypy/plugins/dataclasses.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,11 @@ def transform(self) -> bool:
400400

401401
def _add_dunder_replace(self, attributes: list[DataclassAttribute]) -> None:
402402
"""Add a `__replace__` method to the class, which is used to replace attributes in the `copy` module."""
403-
args = [attr.to_argument(self._cls.info, of="replace") for attr in attributes]
403+
args = [
404+
attr.to_argument(self._cls.info, of="replace")
405+
for attr in attributes
406+
if attr.is_in_init
407+
]
404408
type_vars = [tv for tv in self._cls.type_vars]
405409
add_method_to_class(
406410
self._api,

test-data/unit/check-dataclasses.test

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2492,12 +2492,14 @@ class Child(Base):
24922492

24932493
[case testDunderReplacePresent]
24942494
# flags: --python-version 3.13
2495-
from dataclasses import dataclass
2495+
from dataclasses import dataclass, field
24962496

24972497
@dataclass
24982498
class Coords:
24992499
x: int
25002500
y: int
2501+
# non-init fields are not allowed with replace:
2502+
z: int = field(init=False)
25012503

25022504

25032505
replaced = Coords(2, 4).__replace__(x=2, y=5)

0 commit comments

Comments
 (0)