]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-36470: Allow dataclasses.replace() to handle InitVars with default values (GH...
authorZackery Spytz <zspytz@gmail.com>
Mon, 5 Apr 2021 19:41:01 +0000 (13:41 -0600)
committerGitHub <noreply@github.com>
Mon, 5 Apr 2021 19:41:01 +0000 (12:41 -0700)
Co-Authored-By: Claudiu Popa <pcmanticore@gmail.com>
Automerge-Triggered-By: GH:ericvsmith
Lib/dataclasses.py
Lib/test/test_dataclasses.py
Misc/NEWS.d/next/Library/2020-06-13-23-33-32.bpo-36470.oi6Kdb.rst [new file with mode: 0644]

index 422a95cebe8534e70009b267299d3fb949e916d6..3de2ec04ad370828ad540767ada6b4684071291d 100644 (file)
@@ -1300,7 +1300,7 @@ def replace(obj, /, **changes):
             continue
 
         if f.name not in changes:
-            if f._field_type is _FIELD_INITVAR:
+            if f._field_type is _FIELD_INITVAR and f.default is MISSING:
                 raise ValueError(f"InitVar {f.name!r} "
                                  'must be specified with replace()')
             changes[f.name] = getattr(obj, f.name)
index 0bfed41b369d19c6b084b5be77e7b5e1fd318b07..4f5c3c8aab167b31f2c324f9e791c8c40ec8396d 100644 (file)
@@ -3251,6 +3251,24 @@ class TestReplace(unittest.TestCase):
         c = replace(c, x=3, y=5)
         self.assertEqual(c.x, 15)
 
+    def test_initvar_with_default_value(self):
+        @dataclass
+        class C:
+            x: int
+            y: InitVar[int] = None
+            z: InitVar[int] = 42
+
+            def __post_init__(self, y, z):
+                if y is not None:
+                    self.x += y
+                if z is not None:
+                    self.x += z
+
+        c = C(x=1, y=10, z=1)
+        self.assertEqual(replace(c), C(x=12))
+        self.assertEqual(replace(c, y=4), C(x=12, y=4, z=42))
+        self.assertEqual(replace(c, y=4, z=1), C(x=12, y=4, z=1))
+
     def test_recursive_repr(self):
         @dataclass
         class C:
diff --git a/Misc/NEWS.d/next/Library/2020-06-13-23-33-32.bpo-36470.oi6Kdb.rst b/Misc/NEWS.d/next/Library/2020-06-13-23-33-32.bpo-36470.oi6Kdb.rst
new file mode 100644 (file)
index 0000000..9b6ab99
--- /dev/null
@@ -0,0 +1,2 @@
+Fix dataclasses with ``InitVar``\s and :func:`~dataclasses.replace()`. Patch
+by Claudiu Popa.