summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2021-04-05 20:07:38 (GMT)
committerGitHub <noreply@github.com>2021-04-05 20:07:38 (GMT)
commit013c30e5fcee449cee63354d34585d6111782c82 (patch)
treef820da2a47b1caed8ea5629528caab7113095033
parent82cd24a03c09b93ed0bce0ad7a670d2e97c282c6 (diff)
downloadcpython-013c30e5fcee449cee63354d34585d6111782c82.zip
cpython-013c30e5fcee449cee63354d34585d6111782c82.tar.gz
cpython-013c30e5fcee449cee63354d34585d6111782c82.tar.bz2
bpo-36470: Allow dataclasses.replace() to handle InitVars with default values (GH-20867) (GH-25200)
Co-Authored-By: Claudiu Popa <pcmanticore@gmail.com> Automerge-Triggered-By: GH:ericvsmith (cherry picked from commit 75220674c07abfc90c2cd7862d04cfa2e2354450) Co-authored-by: Zackery Spytz <zspytz@gmail.com> Co-authored-by: Zackery Spytz <zspytz@gmail.com>
-rw-r--r--Lib/dataclasses.py2
-rw-r--r--Lib/test/test_dataclasses.py18
-rw-r--r--Misc/NEWS.d/next/Library/2020-06-13-23-33-32.bpo-36470.oi6Kdb.rst2
3 files changed, 21 insertions, 1 deletions
diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py
index 530d3e9..21c7e0c 100644
--- a/Lib/dataclasses.py
+++ b/Lib/dataclasses.py
@@ -1271,7 +1271,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)
diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py
index b20103b..31caae9 100644
--- a/Lib/test/test_dataclasses.py
+++ b/Lib/test/test_dataclasses.py
@@ -3245,6 +3245,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
index 0000000..9b6ab99
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-06-13-23-33-32.bpo-36470.oi6Kdb.rst
@@ -0,0 +1,2 @@
+Fix dataclasses with ``InitVar``\s and :func:`~dataclasses.replace()`. Patch
+by Claudiu Popa.