Add ConfigView

with python magic to make this possible:

c = Config({"a.b": "c"})
c.view.a.b == "c"
This commit is contained in:
Joscha 2019-05-16 09:14:16 +00:00
parent 71ad02d4e1
commit 31549aa7eb

View file

@ -1,6 +1,6 @@
from typing import Any, Dict from typing import Any, Dict
__all__ = ["Config"] __all__ = ["Fields", "Config", "ConfigView"]
Fields = Dict[str, Any] Fields = Dict[str, Any]
@ -86,3 +86,45 @@ class Config:
self.fields.pop(key) self.fields.pop(key)
else: else:
self.fields[key] = value 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