From 2d35ea3361d239096d63eea6b5899b181ce644a6 Mon Sep 17 00:00:00 2001 From: Nathaniel May Date: Thu, 2 Dec 2021 12:08:09 -0500 Subject: [PATCH 1/6] first pass --- core/dbt/events/base_types.py | 32 +++---- core/dbt/events/functions.py | 32 ++++--- core/dbt/events/types.py | 153 +++++----------------------------- 3 files changed, 54 insertions(+), 163 deletions(-) diff --git a/core/dbt/events/base_types.py b/core/dbt/events/base_types.py index cdf80a36628..d2f0038bcb1 100644 --- a/core/dbt/events/base_types.py +++ b/core/dbt/events/base_types.py @@ -1,7 +1,6 @@ from abc import ABCMeta, abstractmethod, abstractproperty from dataclasses import dataclass from datetime import datetime -import json import os import threading from typing import Any, Optional @@ -67,6 +66,17 @@ def __post_init__(self): self.stack_info: Any = None self.extra: Any = None + def asdict(self): + d = dict() + + for k, v in self.__dict__.items(): + if isinstance(v, Exception): + d[k] = str(v) + else: + d[k] = v + + return d + # TODO add exhaustiveness checking for subclasses # can't use ABCs with @dataclass because of https://github.com/python/mypy/issues/5374 @@ -97,26 +107,6 @@ def level_tag(self) -> str: def message(self) -> str: raise Exception("msg not implemented for Event") - # override this method to convert non-json serializable fields to json. - # for override examples, see existing concrete types. - # - # there is no type-level mechanism to have mypy enforce json serializability, so we just try - # to serialize and raise an exception at runtime when that fails. This safety mechanism - # only works if we have attempted to serialize every concrete event type in our tests. - def fields_to_json(self, field_value: Any) -> Any: - try: - json.dumps(field_value, sort_keys=True) - return field_value - except TypeError: - val_type = type(field_value).__name__ - event_type = type(self).__name__ - return Exception( - f"type {val_type} is not serializable to json." - f" First make sure that the call sites for {event_type} match the type hints" - f" and if they do, you can override Event::fields_to_json in {event_type} in" - " types.py to define your own serialization function to any valid json type" - ) - # exactly one time stamp per concrete event def get_ts(self) -> datetime: if not self.ts: diff --git a/core/dbt/events/functions.py b/core/dbt/events/functions.py index d5cb62d5bc5..2dc32bd5ae1 100644 --- a/core/dbt/events/functions.py +++ b/core/dbt/events/functions.py @@ -132,18 +132,26 @@ def event_to_serializable_dict( ) -> Dict[str, Any]: data = dict() node_info = dict() - if hasattr(e, '__dataclass_fields__'): - if isinstance(e, NodeInfo): - node_info = dataclasses.asdict(e.get_node_info()) - - for field, value in dataclasses.asdict(e).items(): # type: ignore[attr-defined] - if field not in ["code", "report_node_data"]: - _json_value = e.fields_to_json(value) - - if not isinstance(_json_value, Exception): - data[field] = _json_value - else: - data[field] = f"JSON_SERIALIZE_FAILED: {type(value).__name__, 'NA'}" + log_line = dict() + try: + log_line = dataclasses.asdict(e) + json.dumps(log_line) # throwing away unprocessed result, just to make sure it works + except AttributeError: + event_type = type(e).__name__ + raise Exception( + f"type {event_type} is not serializable to json." + f" First make sure that the call sites for {event_type} match the type hints" + f" and if they do, you can override the dataclass method `asdict` in {event_type} in" + " types.py to define your own serialization function to a dictionary of valid json" + " types" + ) + + if isinstance(e, NodeInfo): + node_info = dataclasses.asdict(e.get_node_info()) + + for field, value in log_line.items(): # type: ignore[attr-defined] + if field not in ["code", "report_node_data"]: + data[field] = e event_dict = { 'type': 'log_line', diff --git a/core/dbt/events/types.py b/core/dbt/events/types.py index 87e85e04bf5..af428d119e2 100644 --- a/core/dbt/events/types.py +++ b/core/dbt/events/types.py @@ -115,14 +115,6 @@ class MainEncounteredError(ErrorLevel, Cli): def message(self) -> str: return f"Encountered an error:\n{str(self.e)}" - # overriding default json serialization for this event - def fields_to_json(self, val: Any) -> Any: - # equality on BaseException is not good enough of a comparison here - if isinstance(val, BaseException): - return str(val) - - return val - @dataclass class MainStackTrace(DebugLevel, Cli): @@ -150,12 +142,11 @@ class MainReportArgs(DebugLevel, Cli, File): def message(self): return f"running dbt with arguments {str(self.args)}" - # overriding default json serialization for this event - def fields_to_json(self, val: Any) -> Any: - if isinstance(val, argparse.Namespace): - return str(val) - - return val + def asdict(self) -> dict: + return { + 'code': self.code, + 'args': str(self.args) + } @dataclass @@ -354,13 +345,6 @@ def message(self) -> str: f"{self.reason}\nexception: {self.exc}" ) - # overriding default json serialization for this event - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass class SystemExecutingCmd(DebugLevel, Cli, File): @@ -667,12 +651,11 @@ class AddRelation(DebugLevel, Cli, File, Cache): def message(self) -> str: return f"Adding relation: {str(self.relation)}" - # overriding default json serialization for this event - def fields_to_json(self, val: Any) -> Any: - if isinstance(val, _CachedRelation): - return str(val) - - return val + def asdict(self) -> dict: + return { + 'code': self.code, + 'relation': str(self.relation) + } @dataclass @@ -782,11 +765,11 @@ class AdapterImportError(InfoLevel, Cli, File): def message(self) -> str: return f"Error importing adapter: {self.exc}" - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val()) - - return val + def asdict(self) -> dict: + return { + 'code': self.code, + 'exc': str(self.exc) + } @dataclass @@ -842,12 +825,6 @@ class ProfileLoadError(ShowException, DebugLevel, Cli, File): def message(self) -> str: return f"Profile not loaded due to error: {self.exc}" - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass class ProfileNotFound(InfoLevel, Cli, File): @@ -885,12 +862,6 @@ def message(self) -> str: ) return error - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - # TODO: Remove? (appears to be uncalled) @dataclass @@ -901,17 +872,11 @@ class HandleInternalException(ShowException, DebugLevel, Cli, File): def message(self) -> str: return str(self.exc) - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - # TODO: Remove? (appears to be uncalled) @dataclass -class MessageHandleGenericException(ErrorLevel, Cli, File): +class MessageHandleGenericException(ShowException, ErrorLevel, Cli, File): build_path: str unique_id: str exc: Exception @@ -927,12 +892,6 @@ def message(self) -> str: error=str(self.exc).strip() ) - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - # TODO: Remove? (appears to be uncalled) @@ -1110,12 +1069,6 @@ class ParsedFileLoadFailed(ShowException, DebugLevel, Cli, File): def message(self) -> str: return f"Failed to load parsed file from disk at {self.path}: {self.exc}" - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass class PartialParseSaveFileNotFound(InfoLevel, Cli, File): @@ -1322,34 +1275,22 @@ def message(self) -> str: @dataclass -class RunningOperationCaughtError(ErrorLevel, Cli, File): +class RunningOperationCaughtError(ShowException, ErrorLevel, Cli, File): exc: Exception code: str = "Q001" def message(self) -> str: return f'Encountered an error while running operation: {self.exc}' - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass -class RunningOperationUncaughtError(ErrorLevel, Cli, File): +class RunningOperationUncaughtError(ShowException, ErrorLevel, Cli, File): exc: Exception code: str = "FF01" def message(self) -> str: return f'Encountered an error while running operation: {self.exc}' - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass class DbtProjectError(ErrorLevel, Cli, File): @@ -1360,19 +1301,13 @@ def message(self) -> str: @dataclass -class DbtProjectErrorException(ErrorLevel, Cli, File): +class DbtProjectErrorException(ShowException, ErrorLevel, Cli, File): exc: Exception code: str = "A010" def message(self) -> str: return f" ERROR: {str(self.exc)}" - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass class DbtProfileError(ErrorLevel, Cli, File): @@ -1383,19 +1318,13 @@ def message(self) -> str: @dataclass -class DbtProfileErrorException(ErrorLevel, Cli, File): +class DbtProfileErrorException(ShowException, ErrorLevel, Cli, File): exc: Exception code: str = "A012" def message(self) -> str: return f" ERROR: {str(self.exc)}" - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass class ProfileListTitle(InfoLevel, Cli, File): @@ -1443,15 +1372,9 @@ class CatchableExceptionOnRun(ShowException, DebugLevel, Cli, File): def message(self) -> str: return str(self.exc) - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass -class InternalExceptionOnRun(DebugLevel, Cli, File): +class InternalExceptionOnRun(ShowException, DebugLevel, Cli, File): build_path: str exc: Exception code: str = "W003" @@ -1469,12 +1392,6 @@ def message(self) -> str: note=INTERNAL_ERROR_STRING ) - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - # This prints the stack trace at the debug level while allowing just the nice exception message # at the error level - or whatever other level chosen. Used in multiple places. @@ -1487,7 +1404,7 @@ def message(self) -> str: @dataclass -class GenericExceptionOnRun(ErrorLevel, Cli, File): +class GenericExceptionOnRun(ShowException, ErrorLevel, Cli, File): build_path: str unique_id: str exc: Exception @@ -1503,12 +1420,6 @@ def message(self) -> str: error=str(self.exc).strip() ) - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass class NodeConnectionReleaseError(ShowException, DebugLevel, Cli, File): @@ -1520,12 +1431,6 @@ def message(self) -> str: return ('Error releasing connection for node {}: {!s}' .format(self.node_name, self.exc)) - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass class CheckCleanPath(InfoLevel, Cli): @@ -1846,12 +1751,6 @@ class SQlRunnerException(ShowException, DebugLevel, Cli, File): def message(self) -> str: return f"Got an exception: {self.exc}" - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass class CheckNodeTestFailure(InfoLevel, Cli, File): @@ -2596,7 +2495,7 @@ def message(self) -> str: @dataclass -class GeneralWarningException(WarnLevel, Cli, File): +class GeneralWarningException(ShowException, WarnLevel, Cli, File): exc: Exception log_fmt: str code: str = "Z047" @@ -2606,12 +2505,6 @@ def message(self) -> str: return self.log_fmt.format(str(self.exc)) return str(self.exc) - def fields_to_json(self, val: Any) -> Any: - if val == self.exc: - return str(val) - - return val - @dataclass class EventBufferFull(WarnLevel, Cli, File): From a6c09e740987b5ad777edff3c991ee93c6321272 Mon Sep 17 00:00:00 2001 From: Nathaniel May Date: Thu, 2 Dec 2021 13:18:06 -0500 Subject: [PATCH 2/6] fix the rest of the things --- core/dbt/adapters/base/impl.py | 2 +- core/dbt/events/functions.py | 10 +++++---- core/dbt/events/types.py | 38 ++++++++++++++++++++-------------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/core/dbt/adapters/base/impl.py b/core/dbt/adapters/base/impl.py index f8ac6d5d4fa..deeb06d84dd 100644 --- a/core/dbt/adapters/base/impl.py +++ b/core/dbt/adapters/base/impl.py @@ -291,7 +291,7 @@ def _schema_is_cached(self, database: Optional[str], schema: str) -> bool: if (database, schema) not in self.cache: fire_event( CacheMiss( - conn_name=self.nice_connection_name, + conn_name=self.nice_connection_name(), database=database, schema=schema ) diff --git a/core/dbt/events/functions.py b/core/dbt/events/functions.py index 2dc32bd5ae1..d7fbc597156 100644 --- a/core/dbt/events/functions.py +++ b/core/dbt/events/functions.py @@ -134,11 +134,13 @@ def event_to_serializable_dict( node_info = dict() log_line = dict() try: - log_line = dataclasses.asdict(e) - json.dumps(log_line) # throwing away unprocessed result, just to make sure it works + if hasattr(e, 'asdict'): + log_line = dataclasses.asdict(e, dict_factory=type(e).asdict) # type: ignore + else: + log_line = dataclasses.asdict(e) except AttributeError: event_type = type(e).__name__ - raise Exception( + raise Exception( # TODO this may hang async threads f"type {event_type} is not serializable to json." f" First make sure that the call sites for {event_type} match the type hints" f" and if they do, you can override the dataclass method `asdict` in {event_type} in" @@ -151,7 +153,7 @@ def event_to_serializable_dict( for field, value in log_line.items(): # type: ignore[attr-defined] if field not in ["code", "report_node_data"]: - data[field] = e + data[field] = value event_dict = { 'type': 'log_line', diff --git a/core/dbt/events/types.py b/core/dbt/events/types.py index af428d119e2..c5c8036cf08 100644 --- a/core/dbt/events/types.py +++ b/core/dbt/events/types.py @@ -142,11 +142,9 @@ class MainReportArgs(DebugLevel, Cli, File): def message(self): return f"running dbt with arguments {str(self.args)}" - def asdict(self) -> dict: - return { - 'code': self.code, - 'args': str(self.args) - } + @classmethod + def asdict(cls, data: list) -> dict: + return dict((k, str(v)) for k, v in data) @dataclass @@ -526,7 +524,7 @@ def message(self) -> str: @dataclass class CacheMiss(DebugLevel, Cli, File): - conn_name: Any # TODO mypy says this is `Callable[[], str]`?? ¯\_(ツ)_/¯ + conn_name: str database: Optional[str] schema: str code: str = "E013" @@ -548,6 +546,14 @@ class ListRelations(DebugLevel, Cli, File): def message(self) -> str: return f"with database={self.database}, schema={self.schema}, relations={self.relations}" + @classmethod + def asdict(cls, data: list) -> dict: + d = dict() + for k, v in data: + if type(v) == list: + d[k] = [str(x) for x in v] + return d + @dataclass class ConnectionUsed(DebugLevel, Cli, File): @@ -651,11 +657,9 @@ class AddRelation(DebugLevel, Cli, File, Cache): def message(self) -> str: return f"Adding relation: {str(self.relation)}" - def asdict(self) -> dict: - return { - 'code': self.code, - 'relation': str(self.relation) - } + @classmethod + def asdict(cls, data: list) -> dict: + return dict((k, str(v)) for k, v in data) @dataclass @@ -765,11 +769,9 @@ class AdapterImportError(InfoLevel, Cli, File): def message(self) -> str: return f"Error importing adapter: {self.exc}" - def asdict(self) -> dict: - return { - 'code': self.code, - 'exc': str(self.exc) - } + @classmethod + def asdict(cls, data: list) -> dict: + return dict((k, str(v)) for k, v in data) @dataclass @@ -2221,6 +2223,10 @@ class NodeFinished(DebugLevel, Cli, File, NodeInfo): def message(self) -> str: return f"Finished running node {self.unique_id}" + @classmethod + def asdict(cls, data: list) -> dict: + return dict((k, str(v)) for k, v in data) + @dataclass class QueryCancelationUnsupported(InfoLevel, Cli, File): From e3f859ef87c010c1f7f83b7cdc89fc96b5f512b6 Mon Sep 17 00:00:00 2001 From: Nathaniel May Date: Thu, 2 Dec 2021 13:22:39 -0500 Subject: [PATCH 3/6] revert showexception additions --- core/dbt/events/types.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/dbt/events/types.py b/core/dbt/events/types.py index c5c8036cf08..4eb1c81d43d 100644 --- a/core/dbt/events/types.py +++ b/core/dbt/events/types.py @@ -878,7 +878,7 @@ def message(self) -> str: @dataclass -class MessageHandleGenericException(ShowException, ErrorLevel, Cli, File): +class MessageHandleGenericException(ErrorLevel, Cli, File): build_path: str unique_id: str exc: Exception @@ -1277,7 +1277,7 @@ def message(self) -> str: @dataclass -class RunningOperationCaughtError(ShowException, ErrorLevel, Cli, File): +class RunningOperationCaughtError(ErrorLevel, Cli, File): exc: Exception code: str = "Q001" @@ -1286,7 +1286,7 @@ def message(self) -> str: @dataclass -class RunningOperationUncaughtError(ShowException, ErrorLevel, Cli, File): +class RunningOperationUncaughtError(ErrorLevel, Cli, File): exc: Exception code: str = "FF01" @@ -1303,7 +1303,7 @@ def message(self) -> str: @dataclass -class DbtProjectErrorException(ShowException, ErrorLevel, Cli, File): +class DbtProjectErrorException(ErrorLevel, Cli, File): exc: Exception code: str = "A010" @@ -1320,7 +1320,7 @@ def message(self) -> str: @dataclass -class DbtProfileErrorException(ShowException, ErrorLevel, Cli, File): +class DbtProfileErrorException(ErrorLevel, Cli, File): exc: Exception code: str = "A012" @@ -1376,7 +1376,7 @@ def message(self) -> str: @dataclass -class InternalExceptionOnRun(ShowException, DebugLevel, Cli, File): +class InternalExceptionOnRun(DebugLevel, Cli, File): build_path: str exc: Exception code: str = "W003" @@ -1406,7 +1406,7 @@ def message(self) -> str: @dataclass -class GenericExceptionOnRun(ShowException, ErrorLevel, Cli, File): +class GenericExceptionOnRun(ErrorLevel, Cli, File): build_path: str unique_id: str exc: Exception @@ -2501,7 +2501,7 @@ def message(self) -> str: @dataclass -class GeneralWarningException(ShowException, WarnLevel, Cli, File): +class GeneralWarningException(WarnLevel, Cli, File): exc: Exception log_fmt: str code: str = "Z047" From 871122e3f64d46163366c88df73d9c4fd7d9b973 Mon Sep 17 00:00:00 2001 From: Nathaniel May Date: Thu, 2 Dec 2021 13:29:15 -0500 Subject: [PATCH 4/6] by default convert exceptions to strings --- core/dbt/events/base_types.py | 22 +++++++++++----------- core/dbt/events/functions.py | 5 +---- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/core/dbt/events/base_types.py b/core/dbt/events/base_types.py index d2f0038bcb1..ec22f5fb0c8 100644 --- a/core/dbt/events/base_types.py +++ b/core/dbt/events/base_types.py @@ -66,17 +66,6 @@ def __post_init__(self): self.stack_info: Any = None self.extra: Any = None - def asdict(self): - d = dict() - - for k, v in self.__dict__.items(): - if isinstance(v, Exception): - d[k] = str(v) - else: - d[k] = v - - return d - # TODO add exhaustiveness checking for subclasses # can't use ABCs with @dataclass because of https://github.com/python/mypy/issues/5374 @@ -136,6 +125,17 @@ def get_invocation_id(cls) -> str: from dbt.events.functions import get_invocation_id return get_invocation_id() + # default dict factory for all events. can override on concrete classes. + @classmethod + def asdict(cls, data: list) -> dict: + d = dict() + for k, v in data: + if isinstance(v, Exception): + d[k] = str(v) + else: + d[k] = v + return d + @dataclass # type: ignore class NodeInfo(Event, metaclass=ABCMeta): diff --git a/core/dbt/events/functions.py b/core/dbt/events/functions.py index d7fbc597156..e749ae6b4a2 100644 --- a/core/dbt/events/functions.py +++ b/core/dbt/events/functions.py @@ -134,10 +134,7 @@ def event_to_serializable_dict( node_info = dict() log_line = dict() try: - if hasattr(e, 'asdict'): - log_line = dataclasses.asdict(e, dict_factory=type(e).asdict) # type: ignore - else: - log_line = dataclasses.asdict(e) + log_line = dataclasses.asdict(e, dict_factory=type(e).asdict) except AttributeError: event_type = type(e).__name__ raise Exception( # TODO this may hang async threads From d570f9b08da798ba909c2713fbf19a4d52e2588e Mon Sep 17 00:00:00 2001 From: Nathaniel May Date: Thu, 2 Dec 2021 13:53:45 -0500 Subject: [PATCH 5/6] moar fixez --- core/dbt/events/base_types.py | 6 +++++- core/dbt/events/types.py | 16 ++++++++++++++++ test/unit/test_events.py | 14 +++++--------- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/core/dbt/events/base_types.py b/core/dbt/events/base_types.py index ec22f5fb0c8..c4c8bf3f591 100644 --- a/core/dbt/events/base_types.py +++ b/core/dbt/events/base_types.py @@ -130,8 +130,12 @@ def get_invocation_id(cls) -> str: def asdict(cls, data: list) -> dict: d = dict() for k, v in data: - if isinstance(v, Exception): + # stringify all exceptions + if isinstance(v, Exception) or isinstance(v, BaseException): d[k] = str(v) + # skip all binary data + elif isinstance(v, bytes): + continue else: d[k] = v return d diff --git a/core/dbt/events/types.py b/core/dbt/events/types.py index 4eb1c81d43d..72751abd740 100644 --- a/core/dbt/events/types.py +++ b/core/dbt/events/types.py @@ -613,6 +613,9 @@ class SchemaCreation(DebugLevel, Cli, File): def message(self) -> str: return f'Creating schema "{self.relation}"' + @classmethod + def asdict(cls, data: list) -> dict: + return dict((k, str(v)) for k, v in data) @dataclass class SchemaDrop(DebugLevel, Cli, File): @@ -622,6 +625,10 @@ class SchemaDrop(DebugLevel, Cli, File): def message(self) -> str: return f'Dropping schema "{self.relation}".' + @classmethod + def asdict(cls, data: list) -> dict: + return dict((k, str(v)) for k, v in data) + # TODO pretty sure this is only ever called in dead code # see: core/dbt/adapters/cache.py _add_link vs add_link @@ -680,6 +687,15 @@ class DropCascade(DebugLevel, Cli, File, Cache): def message(self) -> str: return f"drop {self.dropped} is cascading to {self.consequences}" + @classmethod + def asdict(cls, data: list) -> dict: + d = dict() + for k, v in data: + if isinstance(v, list): + d[k] = [str(x) for x in v] + else: + d[k] = str(v) + return d @dataclass class DropRelation(DebugLevel, Cli, File, Cache): diff --git a/test/unit/test_events.py b/test/unit/test_events.py index 34dcff3baf1..a31ac4ae1a4 100644 --- a/test/unit/test_events.py +++ b/test/unit/test_events.py @@ -108,10 +108,6 @@ def test_buffer_populates(self): # EVENT_HISTORY.count(UnitTestInfo(msg='Test Event 1', code='T006')) == 0 # ) -def dump_callable(): - return dict() - - def MockNode(): return ParsedModelNode( alias='model_one', @@ -221,10 +217,10 @@ def MockNode(): old_key=_ReferenceKey(database="", schema="", identifier=""), new_key=_ReferenceKey(database="", schema="", identifier="") ), - DumpBeforeAddGraph(dump_callable), - DumpAfterAddGraph(dump_callable), - DumpBeforeRenameSchema(dump_callable), - DumpAfterRenameSchema(dump_callable), + DumpBeforeAddGraph(dict()), + DumpAfterAddGraph(dict()), + DumpBeforeRenameSchema(dict()), + DumpAfterRenameSchema(dict()), AdapterImportError(ModuleNotFoundError()), PluginLoadError(), SystemReportReturnCode(returncode=0), @@ -429,7 +425,7 @@ def test_all_serializable(self): # if we have everything we need to test, try to serialize everything for event in sample_values: - d = event_to_serializable_dict(event, lambda dt: dt.isoformat(), lambda x: x.message()) + d = event_to_serializable_dict(event, lambda _: event.get_ts_rfc3339(), lambda x: x.message()) try: json.dumps(d) except TypeError as e: From 0caa5798f5943df7d5ec80d197fa4810b6b9193d Mon Sep 17 00:00:00 2001 From: Nathaniel May Date: Thu, 2 Dec 2021 13:56:37 -0500 Subject: [PATCH 6/6] lint fixes --- core/dbt/events/types.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/dbt/events/types.py b/core/dbt/events/types.py index 72751abd740..8df29c8bd2e 100644 --- a/core/dbt/events/types.py +++ b/core/dbt/events/types.py @@ -617,6 +617,7 @@ def message(self) -> str: def asdict(cls, data: list) -> dict: return dict((k, str(v)) for k, v in data) + @dataclass class SchemaDrop(DebugLevel, Cli, File): relation: BaseRelation @@ -694,9 +695,10 @@ def asdict(cls, data: list) -> dict: if isinstance(v, list): d[k] = [str(x) for x in v] else: - d[k] = str(v) + d[k] = str(v) # type: ignore return d + @dataclass class DropRelation(DebugLevel, Cli, File, Cache): dropped: _ReferenceKey