gh-108751: Add copy.replace() function#108752
Conversation
It creates a modified copy of an object by calling the object's __replace__() method. It is a generalization of dataclasses.replace(), named tuple's _replace() method and replace() methods in various classes, and supports all these stdlib classes.
e0d9d26 to
07dd17c
Compare
Doc/library/copy.rst
Outdated
| single: __replace__() (replace protocol) | ||
|
|
||
| Function :func:`replace` is more limited than :func:`copy` and :func:`deepcopy`, | ||
| and only supports named tuples, dataclasses, and other classes which |
There was a problem hiding this comment.
| and only supports named tuples, dataclasses, and other classes which | |
| and only supports :term:`named tuples <named tuple>`, :mod:`dataclasses`, and other classes which |
(I haven’t double checked if named tuple or namedtuple is the right key)
There was a problem hiding this comment.
Actually, it does not support named tuples in general. It currently only supports named tuples created by collections.namedtuple().
| func = getattr(cls, '__replace__', None) | ||
| if func is None: | ||
| raise TypeError(f"replace() does not support {cls.__name__} objects") | ||
| return func(obj, **changes) |
There was a problem hiding this comment.
This is a cool feature for very little code!
|
There's a new commit after the PR has been approved. @rhettinger: please review the changes made to this pull request. |
|
This change introduced a regression: see issue #109052. With this change, |
| ---- | ||
|
|
||
| * Add :func:`copy.replace` function which allows to create a modified copy of | ||
| an object, which is especially usefule for immutable objects. |
There was a problem hiding this comment.
Thanks. Do you mind to create a PR to fix this typo?
|
Would it make sense to add support for dict? >>> d={'x': 1}
>>> copy.replace(d, x=2)
TypeError: replace() does not support dict objectsIt would be an alternative to: >>> d={'x': 1}
>>> dict(d, x=2)
{'x': 2}
>>> {**d, 'x': 2}
{'x': 2} |
|
Nice feature. |
Perhaps no, because it erodes the difference between an object and a dict (as in JavaScript). And you already have other ways to do this with dicts. |
It creates a modified copy of an object by calling the object's
__replace__()method.It is a generalization of dataclasses.replace(), named tuple's _replace() method and replace() methods in various classes, and supports all these stdlib classes.
📚 Documentation preview 📚: https://cpython-previews--108752.org.readthedocs.build/