diff --git a/.changes/unreleased/Under the Hood-20240201-125416.yaml b/.changes/unreleased/Under the Hood-20240201-125416.yaml new file mode 100644 index 00000000000..ae1fab79ab7 --- /dev/null +++ b/.changes/unreleased/Under the Hood-20240201-125416.yaml @@ -0,0 +1,6 @@ +kind: Under the Hood +body: Start using `Mergeable` from dbt-common +time: 2024-02-01T12:54:16.462414-08:00 +custom: + Author: QMalcolm + Issue: "9505" diff --git a/core/dbt/contracts/graph/unparsed.py b/core/dbt/contracts/graph/unparsed.py index a5ddf70560b..ba78f2d4860 100644 --- a/core/dbt/contracts/graph/unparsed.py +++ b/core/dbt/contracts/graph/unparsed.py @@ -7,6 +7,7 @@ AdditionalPropertiesAllowed, AdditionalPropertiesMixin, ) +from dbt_common.contracts.util import Mergeable from dbt_common.exceptions import DbtInternalError, CompilationError from dbt_common.dataclass_schema import ( dbtClassMixin, @@ -22,10 +23,7 @@ MaturityType, MeasureAggregationParameters, ) -from dbt.contracts.util import ( - Mergeable, - Replaceable, -) +from dbt.contracts.util import Replaceable # trigger the PathEncoder import dbt_common.helper_types # noqa:F401 diff --git a/core/dbt/contracts/project.py b/core/dbt/contracts/project.py index 33db4e73fcf..01c2f063980 100644 --- a/core/dbt/contracts/project.py +++ b/core/dbt/contracts/project.py @@ -1,7 +1,8 @@ from dbt import deprecations -from dbt.contracts.util import Replaceable, Mergeable, list_str, Identifier +from dbt.contracts.util import Replaceable, list_str, Identifier from dbt.adapters.contracts.connection import QueryComment from dbt_common.helper_types import NoValue +from dbt_common.contracts.util import Mergeable from dbt_common.dataclass_schema import ( dbtClassMixin, ValidationError, diff --git a/core/dbt/contracts/util.py b/core/dbt/contracts/util.py index 158dbac4642..b4029f9897a 100644 --- a/core/dbt/contracts/util.py +++ b/core/dbt/contracts/util.py @@ -1,8 +1,9 @@ -import dataclasses from typing import List, Any, Tuple from dbt_common.dataclass_schema import ValidatedStringMixin, ValidationError -from dbt_common.contracts.util import Replaceable + +# Leave imports of `Mergeable` and `Replaceable` to preserve import paths +from dbt_common.contracts.util import Mergeable, Replaceable # noqa:F401 SourceKey = Tuple[str, str] @@ -24,22 +25,6 @@ class Foo: return [] -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) - - class Identifier(ValidatedStringMixin): """Our definition of a valid Identifier is the same as what's valid for an unquoted database table name.