diff --git a/src/icmtoolchain/config.py b/src/icmtoolchain/config.py index bcdc0a9..c7785d9 100644 --- a/src/icmtoolchain/config.py +++ b/src/icmtoolchain/config.py @@ -153,7 +153,7 @@ class Config(dict[str, Any]): def __setitem__(self, key: str, value: Any, /) -> None: self.set_value_unsafe(key, value, replace_mismatched_types=True) - def merge_config(self, config: Union[dict, 'Config'], *, replace_configs: bool = False, exclusive_lists: bool = False, extend_lists: bool = False, strip_none_from_lists: bool = False) -> None: + def merge_config(self, config: Union[MutableMapping, 'Config'], *, replace_configs: bool = False, exclusive_lists: bool = False, extend_lists: bool = False, strip_none_from_lists: bool = False) -> None: if exclusive_lists: extend_lists = True @@ -208,7 +208,7 @@ class Config(dict[str, Any]): def __delitem__(self, key: str, /) -> None: self.delete_value_unsafe(key, remove_mismatched_types=True) - def as_json(self, *, strip_none: bool = True) -> dict: + def as_json(self, *, strip_none: bool = True) -> MutableMapping: json = {} for key, value in self.items(): if not isinstance(value, Config): diff --git a/src/icmtoolchain/rule_set.py b/src/icmtoolchain/rule_set.py index 38a0b4a..1188982 100644 --- a/src/icmtoolchain/rule_set.py +++ b/src/icmtoolchain/rule_set.py @@ -1,8 +1,9 @@ -from abc import ABCMeta, abstractmethod -from functools import lru_cache -from typing import Dict, MutableSequence, MutableSet, Optional +from abc import ABCMeta +from itertools import chain +from typing import (Any, Dict, MutableMapping, MutableSequence, MutableSet, + Optional) -from .config import Config +from .config import Config, ConfigSupportsKeysAndGetItem from .utils import ensure_not_whitespace @@ -95,10 +96,28 @@ class RuleSetHolder(metaclass=ABCMeta): def remove_rules(self, *rules: str) -> None: self.rule_set.remove_rules(self.properties, *rules) -@lru_cache(maxsize=4096) -def get_rule_set_config(type: Optional[type['Config']]): - if not type: - type = Config - class RuleSetConfig(type, RuleSetHolder): - pass - return RuleSetConfig +class RuleSetConfig(Config): + def __init__(self, map: Optional[ConfigSupportsKeysAndGetItem] = None, defaults: Optional[Config] = None, overrides: Optional[Config] = None): + super().__init__(map=map, defaults=defaults) + self.overrides = overrides + + def get_dict_value(self, key: str) -> Any: + value = super().get_dict_value(key) + if not self.overrides or not key in self.overrides: + return value + overriden_value = self.overrides.get_dict_value(key) + if isinstance(overriden_value, MutableMapping): + if not isinstance(value, MutableMapping): + return overriden_value + if isinstance(value, RuleSetConfig): + return value + if not isinstance(overriden_value, Config): + overriden_value = Config(overriden_value) + config = RuleSetConfig(map=value, overrides=overriden_value) + self.set_value_unsafe(key, config) + return config + if isinstance(overriden_value, MutableSequence): + if not isinstance(value, MutableSequence): + return overriden_value + return list(chain(overriden_value, value)) + return overriden_value