cereal/src/config/parse.py
2026-08-02 22:49:38 +09:00

31 lines
908 B
Python

from typing import Any, TypeVar, Callable
class ParseError(Exception):
"""An error for when parsing a config fails"""
def __init__(self, keypath: list[str], issue: str):
path = '.'.join(keypath)
message = f'{path}: {issue}'
super().__init__(message)
self.keypath = keypath
self.issue = issue
def assert_key_of_type(config: dict[str, Any], key: str, kind: Any):
if key not in config:
raise ParseError([key], 'missing')
if not isinstance(config[key], kind):
raise ParseError([key], f'type of "{key}" was {type(config[key])}, expected {kind}')
T = TypeVar('T')
def parse_nested_config(config: dict[str, Any], key: str, parse: Callable[[dict[str, Any]], T]) -> T:
assert_key_of_type(config, key, dict)
try:
return parse(config[key])
except ParseError as e:
raise ParseError([key, *e.keypath], e.issue)