Source code for gfw.common.collections

"""Utility functions for collections."""

from collections import ChainMap
from collections.abc import Mapping
from typing import Any, TypeVar


K = TypeVar("K")
V = TypeVar("V")


def _deep_update(target: dict[Any, Any], source: Mapping[Any, Any]) -> None:
    """Recursively merge nested mappings."""
    for key, val in source.items():
        if isinstance(val, Mapping) and key in target and isinstance(target[key], Mapping):
            _deep_update(target[key], val)
        else:
            target[key] = val


[docs] class DeepChainMap(ChainMap[K, V]): """A recursive version of ChainMap. Example: >>> base = {"a": {"x": 1}, "b": 2} >>> override = {"a": {"y": 3}} >>> dcm = DeepChainMap(override, base) >>> dcm["a"]["x"] 1 >>> dcm["a"].to_dict() {'x': 1, 'y': 3} """ def __getitem__(self, key: K) -> Any: """Returns the value for key, merging nested mappings into a new DeepChainMap if needed.""" submaps = [m[key] for m in self.maps if key in m] if not submaps: return self.__missing__(key) first = submaps[0] if isinstance(first, Mapping): return DeepChainMap(*submaps) # type: ignore[arg-type] return first
[docs] def to_dict(self) -> dict[K, V]: """Returns a dictionary repr, taking care of any nested DeepChainMap instances.""" d: dict[K, V] = {} for mapping in reversed(self.maps): _deep_update(d, mapping) return d