From 31549aa7ebc3096f040becf57e530145c2e9950d Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 16 May 2019 09:14:16 +0000 Subject: [PATCH] Add ConfigView with python magic to make this possible: c = Config({"a.b": "c"}) c.view.a.b == "c" --- cheuph/euphoria/config.py | 44 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/cheuph/euphoria/config.py b/cheuph/euphoria/config.py index f00a7df..585fdd7 100644 --- a/cheuph/euphoria/config.py +++ b/cheuph/euphoria/config.py @@ -1,6 +1,6 @@ from typing import Any, Dict -__all__ = ["Config"] +__all__ = ["Fields", "Config", "ConfigView"] Fields = Dict[str, Any] @@ -86,3 +86,45 @@ class Config: self.fields.pop(key) else: self.fields[key] = value + + @property + def view(self) -> "ConfigView": + return ConfigView( + self.to_tree(self.default_fields), + self.to_tree(self.fields), + ) + +class ConfigView: + def __init__(self, + default_fields: Any, + fields: Any, + prefix: str = "", + ) -> None: + + self._default_fields = default_fields + self._fields = fields + self._prefix = prefix + + def __getattr__(self, name: str) -> Any: + """ + This function assumes that _default_fields and _fields have the same + dict structure. + """ + + default_field = self._default_fields.get(name) + field = self._fields.get(name) + + if isinstance(field, dict) or isinstance(default_field, dict): + # At least one is a dict, the other is either also a dict of the + # same structure or None. + default_field = default_field or {} + field = field or {} + + return ConfigView(default_field, field, f"{self._prefix}{name}.") + + value = default_field if field is None else field + + if value is None: + raise ConfigException(f"Field {self._prefix}{name} does not exist") + + return value