Skip to content

Commit ab4edc6

Browse files
FastLeenfx
andauthored
Fixed issue when Databricks SDK config objects were overridden for installation config files (#170)
closes #169 --------- Co-authored-by: Serge Smertin <serge.smertin@databricks.com>
1 parent cb1b8f0 commit ab4edc6

File tree

2 files changed

+43
-40
lines changed

2 files changed

+43
-40
lines changed

src/databricks/labs/blueprint/installation.py

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -469,66 +469,62 @@ def _get_list_type_ref(inst: T) -> type[list[T]]:
469469
item_type = type(from_list[0]) # type: ignore[misc]
470470
return list[item_type] # type: ignore[valid-type]
471471

472-
@classmethod
473-
def _marshal(cls, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
472+
def _marshal(self, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
474473
"""The `_marshal` method is a private method that is used to serialize an object of type `type_ref` to
475474
a dictionary. This method is called by the `save` method."""
475+
if inst is None:
476+
return None, False
477+
if isinstance(inst, databricks.sdk.core.Config):
478+
return self._marshal_databricks_config(inst)
476479
if hasattr(inst, "as_dict"):
477480
return inst.as_dict(), True
478481
if dataclasses.is_dataclass(type_ref):
479-
return cls._marshal_dataclass(type_ref, path, inst)
480-
if isinstance(inst, databricks.sdk.core.Config):
481-
return inst.as_dict(), True
482+
return self._marshal_dataclass(type_ref, path, inst)
482483
if type_ref == list:
483-
return cls._marshal_list(type_ref, path, inst)
484+
return self._marshal_list(type_ref, path, inst)
484485
if isinstance(type_ref, enum.EnumMeta):
485-
return cls._marshal_enum(inst)
486+
return self._marshal_enum(inst)
486487
if type_ref == types.NoneType:
487488
return inst, inst is None
488-
if type_ref == databricks.sdk.core.Config:
489-
return cls._marshal_databricks_config(inst)
490-
if type_ref in cls._PRIMITIVES:
489+
if type_ref in self._PRIMITIVES:
491490
return inst, True
492-
return cls._marshal_generic_types(type_ref, path, inst)
491+
return self._marshal_generic_types(type_ref, path, inst)
493492

494-
@classmethod
495-
def _marshal_generic_types(cls, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
493+
def _marshal_generic_types(self, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
496494
# pylint: disable-next=import-outside-toplevel,import-private-name
497495
from typing import ( # type: ignore[attr-defined]
498496
_GenericAlias,
499497
_UnionGenericAlias,
500498
)
501499

502500
if isinstance(type_ref, (types.UnionType, _UnionGenericAlias)): # type: ignore[attr-defined]
503-
return cls._marshal_union(type_ref, path, inst)
501+
return self._marshal_union(type_ref, path, inst)
504502
if isinstance(type_ref, (_GenericAlias, types.GenericAlias)): # type: ignore[attr-defined]
505503
if type_ref.__origin__ in (dict, list) or isinstance(type_ref, types.GenericAlias):
506-
return cls._marshal_generic(type_ref, path, inst)
507-
return cls._marshal_generic_alias(type_ref, inst)
504+
return self._marshal_generic(type_ref, path, inst)
505+
return self._marshal_generic_alias(type_ref, inst)
508506
raise SerdeError(f'{".".join(path)}: unknown: {inst}')
509507

510-
@classmethod
511-
def _marshal_union(cls, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
508+
def _marshal_union(self, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
512509
"""The `_marshal_union` method is a private method that is used to serialize an object of type `type_ref` to
513510
a dictionary. This method is called by the `save` method."""
514511
combo = []
515512
for variant in get_args(type_ref):
516-
value, ok = cls._marshal(variant, [*path, f"(as {variant})"], inst)
513+
value, ok = self._marshal(variant, [*path, f"(as {variant})"], inst)
517514
if ok:
518515
return value, True
519-
combo.append(cls._explain_why(variant, [*path, f"(as {variant})"], inst))
516+
combo.append(self._explain_why(variant, [*path, f"(as {variant})"], inst))
520517
raise SerdeError(f'{".".join(path)}: union: {" or ".join(combo)}')
521518

522-
@classmethod
523-
def _marshal_generic(cls, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
519+
def _marshal_generic(self, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
524520
"""The `_marshal_generic` method is a private method that is used to serialize an object of type `type_ref`
525521
to a dictionary. This method is called by the `save` method."""
526522
type_args = get_args(type_ref)
527523
if not type_args:
528524
raise SerdeError(f"Missing type arguments: {type_args}")
529525
if len(type_args) == 2:
530-
return cls._marshal_dict(type_args[1], path, inst)
531-
return cls._marshal_list(type_args[0], path, inst)
526+
return self._marshal_dict(type_args[1], path, inst)
527+
return self._marshal_list(type_args[0], path, inst)
532528

533529
@staticmethod
534530
def _marshal_generic_alias(type_ref, inst):
@@ -538,35 +534,32 @@ def _marshal_generic_alias(type_ref, inst):
538534
return None, False
539535
return inst, isinstance(inst, type_ref.__origin__) # type: ignore[attr-defined]
540536

541-
@classmethod
542-
def _marshal_list(cls, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
537+
def _marshal_list(self, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
543538
"""The `_marshal_list` method is a private method that is used to serialize an object of type `type_ref` to
544539
a dictionary. This method is called by the `save` method."""
545540
as_list = []
546541
if not isinstance(inst, list):
547542
return None, False
548543
for i, v in enumerate(inst):
549-
value, ok = cls._marshal(type_ref, [*path, f"{i}"], v)
544+
value, ok = self._marshal(type_ref, [*path, f"{i}"], v)
550545
if not ok:
551-
raise SerdeError(cls._explain_why(type_ref, [*path, f"{i}"], v))
546+
raise SerdeError(self._explain_why(type_ref, [*path, f"{i}"], v))
552547
as_list.append(value)
553548
return as_list, True
554549

555-
@classmethod
556-
def _marshal_dict(cls, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
550+
def _marshal_dict(self, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
557551
"""The `_marshal_dict` method is a private method that is used to serialize an object of type `type_ref` to
558552
a dictionary. This method is called by the `save` method."""
559553
if not isinstance(inst, dict):
560554
return None, False
561555
as_dict = {}
562556
for k, v in inst.items():
563-
as_dict[k], ok = cls._marshal(type_ref, [*path, k], v)
557+
as_dict[k], ok = self._marshal(type_ref, [*path, k], v)
564558
if not ok:
565-
raise SerdeError(cls._explain_why(type_ref, [*path, k], v))
559+
raise SerdeError(self._explain_why(type_ref, [*path, k], v))
566560
return as_dict, True
567561

568-
@classmethod
569-
def _marshal_dataclass(cls, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
562+
def _marshal_dataclass(self, type_ref: type, path: list[str], inst: Any) -> tuple[Any, bool]:
570563
"""The `_marshal_dataclass` method is a private method that is used to serialize an object of type `type_ref`
571564
to a dictionary. This method is called by the `save` method."""
572565
if inst is None:
@@ -577,21 +570,29 @@ def _marshal_dataclass(cls, type_ref: type, path: list[str], inst: Any) -> tuple
577570
if origin is typing.ClassVar:
578571
continue
579572
raw = getattr(inst, field)
580-
value, ok = cls._marshal(hint, [*path, field], raw)
573+
if not raw:
574+
continue
575+
value, ok = self._marshal(hint, [*path, field], raw)
581576
if not ok:
582-
raise SerdeError(cls._explain_why(hint, [*path, field], raw))
577+
raise SerdeError(self._explain_why(hint, [*path, field], raw))
583578
if not value:
584579
continue
585580
as_dict[field] = value
586581
return as_dict, True
587582

588-
@staticmethod
589-
def _marshal_databricks_config(inst):
583+
def _marshal_databricks_config(self, inst):
590584
"""The `_marshal_databricks_config` method is a private method that is used to serialize an object of type
591585
`databricks.sdk.core.Config` to a dictionary. This method is called by the `save` method."""
592586
if not inst:
593587
return None, False
594-
return inst.as_dict(), True
588+
current_client_config = self._current_client_config()
589+
remote_file_config = inst.as_dict()
590+
if current_client_config == remote_file_config:
591+
return None, True
592+
return remote_file_config, True
593+
594+
def _current_client_config(self) -> dict:
595+
return self._ws.config.as_dict()
595596

596597
@staticmethod
597598
def _marshal_enum(inst):
@@ -886,6 +887,9 @@ def files(self) -> list[workspace.ObjectInfo]:
886887
def remove(self):
887888
self._removed = True
888889

890+
def _current_client_config(self) -> dict:
891+
return {}
892+
889893
def _overwrite_content(self, filename: str, as_dict: Json, type_ref: type):
890894
self._overwrites[filename] = as_dict
891895

src/databricks/labs/blueprint/paths.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131

3232
from databricks.labs.blueprint import _posixpath
3333

34-
3534
logger = logging.getLogger(__name__)
3635

3736

0 commit comments

Comments
 (0)