From b0a8388a8b7d0b3cd9702644756c44aeb3c62e11 Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Sat, 25 Feb 2023 14:29:54 +0100 Subject: [PATCH] tools.Dict(): ansible template style dictionary with defaults --- tools/tools.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tools/tools.py b/tools/tools.py index ec386c9..87ae83a 100644 --- a/tools/tools.py +++ b/tools/tools.py @@ -26,6 +26,53 @@ class Cache(dict): return r +class Dict(dict): + _initialized: bool = False + + def __init__(self, *args, **kwargs): + if "default" in kwargs: + self.__default = kwargs['default'] + del kwargs['default'] + else: + self.__default = None + + super(Dict, self).__init__(*args, **kwargs) + self.convert() + self._initialized = True + + def convert(self): + for k in self: + if isinstance(self[k], dict) and not isinstance(self[k], Dict): + self[k] = Dict(self[k]) + elif isinstance(self[k], list): + for i in range(len(self[k])): + if isinstance(self[k][i], dict) and not isinstance(self[k][i], Dict): + self[k][i] = Dict(self[k][i]) + + def update(self, other: dict, **kwargs): + super(Dict, self).update(other, **kwargs) + self.convert() + + def __getattr__(self, item): + try: + return self[item] + except KeyError: + if self.__default is None: + raise AttributeError(item) + else: + return self.__default + + def __setattr__(self, key, value): + if not self._initialized: + super(Dict, self).__setattr__(key, value) + else: + self[key] = value + + def __setitem__(self, key, value): + super(Dict, self).__setitem__(key, value) + self.convert() + + def get_script_dir(follow_symlinks: bool = True) -> str: """return path of the executed script""" if getattr(sys, 'frozen', False):