Skip to content

Commit bdee2a3

Browse files
bpo-36470: Allow dataclasses.replace() to handle InitVars with default values (GH-20867) (GH-25201)
Co-Authored-By: Claudiu Popa <pcmanticore@gmail.com> Automerge-Triggered-By: GH:ericvsmith (cherry picked from commit 7522067) Co-authored-by: Zackery Spytz <zspytz@gmail.com> Co-authored-by: Zackery Spytz <zspytz@gmail.com>
1 parent 0f7c77e commit bdee2a3

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

Lib/dataclasses.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1280,7 +1280,7 @@ class C:
12801280
continue
12811281

12821282
if f.name not in changes:
1283-
if f._field_type is _FIELD_INITVAR:
1283+
if f._field_type is _FIELD_INITVAR and f.default is MISSING:
12841284
raise ValueError(f"InitVar {f.name!r} "
12851285
'must be specified with replace()')
12861286
changes[f.name] = getattr(obj, f.name)

Lib/test/test_dataclasses.py

+18
Original file line numberDiff line numberDiff line change
@@ -3252,6 +3252,24 @@ def __post_init__(self, y):
32523252
c = replace(c, x=3, y=5)
32533253
self.assertEqual(c.x, 15)
32543254

3255+
def test_initvar_with_default_value(self):
3256+
@dataclass
3257+
class C:
3258+
x: int
3259+
y: InitVar[int] = None
3260+
z: InitVar[int] = 42
3261+
3262+
def __post_init__(self, y, z):
3263+
if y is not None:
3264+
self.x += y
3265+
if z is not None:
3266+
self.x += z
3267+
3268+
c = C(x=1, y=10, z=1)
3269+
self.assertEqual(replace(c), C(x=12))
3270+
self.assertEqual(replace(c, y=4), C(x=12, y=4, z=42))
3271+
self.assertEqual(replace(c, y=4, z=1), C(x=12, y=4, z=1))
3272+
32553273
def test_recursive_repr(self):
32563274
@dataclass
32573275
class C:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix dataclasses with ``InitVar``\s and :func:`~dataclasses.replace()`. Patch
2+
by Claudiu Popa.

0 commit comments

Comments
 (0)