[SYNPY-1844] When merging dataclasses with nested dataclasses the merge function is now recrursive.#1412
Merged
Conversation
linglp
reviewed
Jun 23, 2026
| del incoming_object[key] | ||
|
|
||
|
|
||
| T = TypeVar("_T") |
Contributor
There was a problem hiding this comment.
What does this mean? Does it mean any type is allowed? I think this is different from the original: typing.Union[ "Project", "Folder", "File", "Table", "Column", "Evaluation" ]
Contributor
Author
There was a problem hiding this comment.
That's correct! This should work with any dataclass, not just the ones currently listed. It was already being called with CurationTask. There's just no dataclass type that I'm aware of.
In fact, it might work with any Python object that has the getattr and setattr methods.
linglp
approved these changes
Jun 23, 2026
linglp
left a comment
Contributor
There was a problem hiding this comment.
LGTM! I verified the fix worked on my end.
BryanFauble
reviewed
Jun 23, 2026
BryanFauble
approved these changes
Jun 23, 2026
BryanFauble
left a comment
Member
There was a problem hiding this comment.
Let's add in that additional test case, otherwise LGTM!
…fferent than the destination dataclass is preserved as-is instead of merging
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem:
merge_dataclass_entitiesinsynapseclient/core/utils.pydid not correctly handle entities containing nested dataclass fields (e.g. aCurationTaskwhosetask_propertiesfield is itself a dataclass).Solution:
merge_dataclass_entitiesrecursive: when both source and destination hold a dataclass instance on the same field, the function now recurses into that nested dataclass and applies the same merge rules field-by-field, rather than blindly replacing the destination value.Noneor not a dataclass — in that case the source value is used directly (existing gap-fill behavior).source,destination, and the return value to use aTypeVar(T) instead of the previous hard-codedUnionof specific model names. This correctly expresses that both arguments must be the same type and the return is that same type, and removes the need to update the annotation whenever a new model is added.TYPE_CHECKINGimport of the specific model names that existed solely to support the old Union annotation.Testing:
TestMergeDataclassEntitiestest class intests/unit/synapseclient/core/unit_test_utils.pycovering:fields_to_ignoreandfields_to_preserve_from_sourcebehaviorNone, destination wins on conflict, sub-fields recurse-merge correctly, and source wins when destination field holds a non-dataclass value