Skip to content

Commit

Permalink
Add Mergeable to contract utils
Browse files Browse the repository at this point in the history
At this moment in time, `Mergeable` is defined in core
[here](https://github.com/dbt-labs/dbt-core/blob/1a5d6922dddf9ffe018d8860bb2f2141594ddbbe/core/dbt/contracts/util.py#L27).
We're curren't in the process of moving data artifacts of nodes defined
in dbt-core's `nodes.py` into dbt-artifacts. Some of these data artifacts
depend on `Mergeable`. We don't want artifacts to depend on core, thus
`Mergeable` has to be moved _somewhere_ upstream. Given `Mergeable`'s
similarity to `Replaceable` it made the most sense to move next to
`Replaceable` here in dbt-common.
  • Loading branch information
QMalcolm committed Feb 1, 2024
1 parent caaab94 commit 65c6656
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions dbt_common/contracts/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,19 @@
class Replaceable:
def replace(self, **kwargs):
return dataclasses.replace(self, **kwargs)


class Mergeable(Replaceable):
def merged(self, *args):
"""Perform a shallow merge, where the last non-None write wins. This is
intended to merge dataclasses that are a collection of optional values.
"""
replacements = {}
cls = type(self)
for arg in args:
for field in dataclasses.fields(cls):
value = getattr(arg, field.name)
if value is not None:
replacements[field.name] = value

return self.replace(**replacements)

0 comments on commit 65c6656

Please sign in to comment.