-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
gh-108751: Add copy.replace() function #108752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
usefule -> useful
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 objects It 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/