diff --git a/.changes/unreleased/Fixes-20221016-173742.yaml b/.changes/unreleased/Fixes-20221016-173742.yaml new file mode 100644 index 00000000000..11d4a8c85f4 --- /dev/null +++ b/.changes/unreleased/Fixes-20221016-173742.yaml @@ -0,0 +1,8 @@ +kind: Fixes +body: Add functors to ensure event types with str-type attributes are initialized + to spec, even when provided non-str type params. +time: 2022-10-16T17:37:42.846683-07:00 +custom: + Author: versusfacit + Issue: "5436" + PR: "5874" diff --git a/core/dbt/events/adapter_endpoint.py b/core/dbt/events/adapter_endpoint.py index aff157ab611..68a73d8aecb 100644 --- a/core/dbt/events/adapter_endpoint.py +++ b/core/dbt/events/adapter_endpoint.py @@ -9,6 +9,7 @@ ) +# N.B. No guarantees for what type param msg is. @dataclass class AdapterLogger: name: str diff --git a/core/dbt/events/base_types.py b/core/dbt/events/base_types.py index 489b70cb1ad..cd3275c02a9 100644 --- a/core/dbt/events/base_types.py +++ b/core/dbt/events/base_types.py @@ -99,6 +99,23 @@ def level_tag(self) -> str: return "error" +# Included to ensure classes with str-type message members are initialized correctly. +@dataclass # type: ignore[misc] +class AdapterEventStringFunctor: + def __post_init__(self): + super().__post_init__() + if not isinstance(self.base_msg, str): + self.base_msg = str(self.base_msg) + + +@dataclass # type: ignore[misc] +class EventStringFunctor: + def __post_init__(self): + super().__post_init__() + if not isinstance(self.msg, str): + self.msg = str(self.msg) + + # prevents an event from going to the file # This should rarely be used in core code. It is currently # only used in integration tests and for the 'clean' command. diff --git a/core/dbt/events/types.py b/core/dbt/events/types.py index 60204138c36..f6e66f941d2 100644 --- a/core/dbt/events/types.py +++ b/core/dbt/events/types.py @@ -7,6 +7,8 @@ WarnLevel, ErrorLevel, Cache, + AdapterEventStringFunctor, + EventStringFunctor, ) from dbt.events.format import format_fancy_output_line, pluralize @@ -309,7 +311,7 @@ def message(self) -> str: @dataclass -class AdapterEventDebug(DebugLevel, pt.AdapterEventDebug): # noqa +class AdapterEventDebug(DebugLevel, AdapterEventStringFunctor, pt.AdapterEventDebug): # noqa def code(self): return "E001" @@ -318,7 +320,7 @@ def message(self): @dataclass -class AdapterEventInfo(InfoLevel, pt.AdapterEventInfo): # noqa +class AdapterEventInfo(InfoLevel, AdapterEventStringFunctor, pt.AdapterEventInfo): # noqa def code(self): return "E002" @@ -327,7 +329,7 @@ def message(self): @dataclass -class AdapterEventWarning(WarnLevel, pt.AdapterEventWarning): # noqa +class AdapterEventWarning(WarnLevel, AdapterEventStringFunctor, pt.AdapterEventWarning): # noqa def code(self): return "E003" @@ -336,7 +338,7 @@ def message(self): @dataclass -class AdapterEventError(ErrorLevel, pt.AdapterEventError): # noqa +class AdapterEventError(ErrorLevel, AdapterEventStringFunctor, pt.AdapterEventError): # noqa def code(self): return "E004" @@ -1218,7 +1220,9 @@ def message(self) -> str: # TODO: switch to storing structured info and calling get_target_failure_msg @dataclass -class InvalidDisabledSourceInTestNode(WarnLevel, pt.InvalidDisabledSourceInTestNode): +class InvalidDisabledSourceInTestNode( + WarnLevel, EventStringFunctor, pt.InvalidDisabledSourceInTestNode +): def code(self): return "I050" @@ -1227,7 +1231,7 @@ def message(self) -> str: @dataclass -class InvalidRefInTestNode(DebugLevel, pt.InvalidRefInTestNode): +class InvalidRefInTestNode(DebugLevel, EventStringFunctor, pt.InvalidRefInTestNode): def code(self): return "I051" @@ -1334,7 +1338,7 @@ def message(self) -> str: @dataclass -class MacroEventInfo(InfoLevel, pt.MacroEventInfo): +class MacroEventInfo(InfoLevel, EventStringFunctor, pt.MacroEventInfo): def code(self): return "M011" @@ -1343,7 +1347,7 @@ def message(self) -> str: @dataclass -class MacroEventDebug(DebugLevel, pt.MacroEventDebug): +class MacroEventDebug(DebugLevel, EventStringFunctor, pt.MacroEventDebug): def code(self): return "M012" @@ -2261,7 +2265,7 @@ def message(self) -> str: @dataclass -class RunResultError(ErrorLevel, pt.RunResultError): +class RunResultError(ErrorLevel, EventStringFunctor, pt.RunResultError): def code(self): return "Z024" @@ -2299,7 +2303,7 @@ def message(self) -> str: @dataclass -class FirstRunResultError(ErrorLevel, pt.FirstRunResultError): +class FirstRunResultError(ErrorLevel, EventStringFunctor, pt.FirstRunResultError): def code(self): return "Z028" @@ -2308,7 +2312,7 @@ def message(self) -> str: @dataclass -class AfterFirstRunResultError(ErrorLevel, pt.AfterFirstRunResultError): +class AfterFirstRunResultError(ErrorLevel, EventStringFunctor, pt.AfterFirstRunResultError): def code(self): return "Z029" @@ -2446,7 +2450,7 @@ def message(self) -> str: @dataclass -class GeneralWarningMsg(WarnLevel, pt.GeneralWarningMsg): +class GeneralWarningMsg(WarnLevel, EventStringFunctor, pt.GeneralWarningMsg): def code(self): return "Z046" @@ -2476,7 +2480,7 @@ def message(self) -> str: @dataclass -class RunResultWarningMessage(WarnLevel, pt.RunResultWarningMessage): +class RunResultWarningMessage(WarnLevel, EventStringFunctor, pt.RunResultWarningMessage): def code(self): return "Z049"