[Python-checkins] bpo-37163: Deprecate passing argument obj of dataclasses.replace() by keyword. (GH-13877)

Serhiy Storchaka webhook-mailer at python.org
Wed Jun 19 03:33:32 EDT 2019


https://github.com/python/cpython/commit/f5b89afde1196ec9f74b7dc0333cec9bc4d4c2db
commit: f5b89afde1196ec9f74b7dc0333cec9bc4d4c2db
branch: 3.8
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2019-06-19T10:33:27+03:00
summary:

bpo-37163: Deprecate passing argument obj of dataclasses.replace() by keyword. (GH-13877)

files:
A Misc/NEWS.d/next/Library/2019-06-07-08-18-05.bpo-37163.36JkUh.rst
M Lib/dataclasses.py
M Lib/test/test_dataclasses.py

diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py
index b035cbb809f8..18713722a764 100644
--- a/Lib/dataclasses.py
+++ b/Lib/dataclasses.py
@@ -1206,7 +1206,7 @@ class C(Base):
                      unsafe_hash=unsafe_hash, frozen=frozen)
 
 
-def replace(obj, **changes):
+def replace(*args, **changes):
     """Return a new object replacing specified fields with new values.
 
     This is especially useful for frozen classes.  Example usage:
@@ -1220,6 +1220,17 @@ class C:
       c1 = replace(c, x=3)
       assert c1.x == 3 and c1.y == 2
       """
+    if len(args) > 1:
+        raise TypeError(f'replace() takes 1 positional argument but {len(args)} were given')
+    if args:
+        obj, = args
+    elif 'obj' in changes:
+        obj = changes.pop('obj')
+        import warnings
+        warnings.warn("Passing 'obj' as keyword argument is deprecated",
+                      DeprecationWarning, stacklevel=2)
+    else:
+        raise TypeError("replace() missing 1 required positional argument: 'obj'")
 
     # We're going to mutate 'changes', but that's okay because it's a
     # new dict, even if called with 'replace(obj, **my_changes)'.
@@ -1255,3 +1266,4 @@ class C:
     # changes that aren't fields, this will correctly raise a
     # TypeError.
     return obj.__class__(**changes)
+replace.__text_signature__ = '(obj, /, **kwargs)'
diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py
index 53e8443c2adf..cb0e18c242d1 100755
--- a/Lib/test/test_dataclasses.py
+++ b/Lib/test/test_dataclasses.py
@@ -3075,6 +3075,13 @@ class C:
         self.assertEqual(c1.x, 3)
         self.assertEqual(c1.y, 2)
 
+        self.assertRaises(TypeError, replace)
+        self.assertRaises(TypeError, replace, c, c)
+        with self.assertWarns(DeprecationWarning):
+            c1 = replace(obj=c, x=3)
+        self.assertEqual(c1.x, 3)
+        self.assertEqual(c1.y, 2)
+
     def test_frozen(self):
         @dataclass(frozen=True)
         class C:
diff --git a/Misc/NEWS.d/next/Library/2019-06-07-08-18-05.bpo-37163.36JkUh.rst b/Misc/NEWS.d/next/Library/2019-06-07-08-18-05.bpo-37163.36JkUh.rst
new file mode 100644
index 000000000000..04cf61d3e099
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-06-07-08-18-05.bpo-37163.36JkUh.rst
@@ -0,0 +1,2 @@
+Deprecated passing ``obj`` argument of :func:`dataclasses.replace` as
+keyword argument.



More information about the Python-checkins mailing list