diff options
-rw-r--r-- | kvmd/apps/__init__.py | 10 | ||||
-rw-r--r-- | kvmd/yamlconf/__init__.py | 10 |
2 files changed, 17 insertions, 3 deletions
diff --git a/kvmd/apps/__init__.py b/kvmd/apps/__init__.py index b3197306..9c8f5c03 100644 --- a/kvmd/apps/__init__.py +++ b/kvmd/apps/__init__.py @@ -46,6 +46,7 @@ from ..plugins.msd import get_msd_class from ..plugins.ugpio import get_ugpio_driver_class from ..yamlconf import ConfigError +from ..yamlconf import manual_validated from ..yamlconf import make_config from ..yamlconf import Section from ..yamlconf import Option @@ -185,7 +186,8 @@ def _patch_dynamic( # pylint: disable=too-many-locals "__gpio__": {}, **tools.rget(raw_config, "kvmd", "gpio", "drivers"), }.items(): - driver = valid_ugpio_driver(driver) + with manual_validated(driver, "kvmd", "gpio", "drivers", "<key>"): + driver = valid_ugpio_driver(driver) driver_type = valid_stripped_string_not_empty(params.get("type", "gpio")) scheme["kvmd"]["gpio"]["drivers"][driver] = { "type": Option(driver_type, type=valid_stripped_string_not_empty), @@ -194,8 +196,10 @@ def _patch_dynamic( # pylint: disable=too-many-locals drivers.add(driver) for (channel, params) in tools.rget(raw_config, "kvmd", "gpio", "scheme").items(): - channel = valid_ugpio_channel(channel) - mode = valid_ugpio_mode(params.get("mode", "")) + with manual_validated(channel, "kvmd", "gpio", "scheme", "<key>"): + channel = valid_ugpio_channel(channel) + with manual_validated(params.get("mode", ""), "kvmd", "gpio", "scheme", channel, "mode"): + mode = valid_ugpio_mode(params.get("mode", "")) scheme["kvmd"]["gpio"]["scheme"][channel] = { "driver": Option("__gpio__", type=(lambda arg: valid_ugpio_driver(arg, drivers))), "pin": Option(-1, type=valid_gpio_pin), diff --git a/kvmd/yamlconf/__init__.py b/kvmd/yamlconf/__init__.py index a253d449..9de5bee3 100644 --- a/kvmd/yamlconf/__init__.py +++ b/kvmd/yamlconf/__init__.py @@ -20,11 +20,13 @@ # ========================================================================== # +import contextlib import json from typing import Tuple from typing import List from typing import Dict +from typing import Generator from typing import Callable from typing import Optional from typing import Any @@ -129,6 +131,14 @@ class Option: # ===== +def manual_validated(value: Any, *path: str) -> Generator[None, None, None]: + try: + yield + except (TypeError, ValueError) as err: + raise ConfigError(f"Invalid value {value!r} for key {'/'.join(path)!r}: {err}") + + def make_config(raw: Dict[str, Any], scheme: Dict[str, Any], _keys: Tuple[str, ...]=()) -> Section: if not isinstance(raw, dict): raise ConfigError(f"The node {('/'.join(_keys) or '/')!r} must be a dictionary") |