| 1234567891011121314151617181920212223242526272829303132333435363738394041424344 |
- from __future__ import annotations
- from copy import deepcopy
- from pathlib import Path
- from typing import Any
- import yaml
- def load_yaml_config(path: str | Path) -> dict[str, Any]:
- with Path(path).open("r", encoding="utf-8") as handle:
- return yaml.safe_load(handle) or {}
- def deep_update(dst: dict[str, Any], src: dict[str, Any]) -> dict[str, Any]:
- for key, value in src.items():
- if isinstance(value, dict) and isinstance(dst.get(key), dict):
- deep_update(dst[key], value)
- else:
- dst[key] = value
- return dst
- def apply_dotlist_overrides(cfg: dict[str, Any], overrides: list[str] | None) -> dict[str, Any]:
- if not overrides:
- return cfg
- updated = deepcopy(cfg)
- for item in overrides:
- if "=" not in item:
- raise ValueError(f"Invalid override '{item}'. Expected key=value format.")
- key, raw_value = item.split("=", 1)
- value = yaml.safe_load(raw_value)
- parts = key.split(".")
- current = updated
- for part in parts[:-1]:
- if part not in current or not isinstance(current[part], dict):
- current[part] = {}
- current = current[part]
- current[parts[-1]] = value
- return updated
- __all__ = ["load_yaml_config", "deep_update", "apply_dotlist_overrides"]
|