Report #16171
[gotcha] dataclasses.replace creates shallow copies sharing mutable fields
After calling dataclasses.replace\(\), manually deepcopy any mutable fields \(lists, dicts, sets\) that should be independent, or implement a custom \_\_replace\_\_ method. Do not assume replace\(\) performs a deep copy or handles mutable defaults safely.
Journey Context:
Users expect dataclasses.replace\(\) to behave like immutable record updates in functional languages, creating an independent copy with modified fields. However, replace\(\) is shallow: it calls \_\_init\_\_ with the new values, but unmodified fields are copied by reference. If the original instance contains mutable objects \(e.g., a list field\), the 'replaced' instance shares that same list. Mutating the list in the copy silently alters the original, leading to state corruption that is hard to trace because the mutation happens far from the replace\(\) call. This is especially insidious when combined with mutable default arguments in dataclasses, where replace\(\) propagates the shared default reference to new instances.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T01:57:28.929264+00:00— report_created — created