Skip to content

Dict operators

commons.dict_operators

Functions:

Name Description
deep_merge

Recursively merge two dictionaries, with override values taking precedence.

unflatten

Convert a flat dictionary with dotted keys to a nested structure.

flatten

Convert a nested dictionary to a flat dictionary with dotted keys.

deep_merge

deep_merge(base: dict, override: dict) -> dict

Recursively merge two dictionaries, with override values taking precedence.

When both base and override have a dict value for the same key, the dicts are merged recursively. For all other cases (non-dict values, or key only in one dict), the override value replaces the base value.

Parameters:

Name Type Description Default
base dict

The base dictionary to merge into.

required
override dict

The dictionary whose values take precedence.

required

Returns:

Type Description
dict

A new dictionary with merged values. Neither input dict is mutated.

Source code in src/commons/dict_operators.py
def deep_merge(base: dict, override: dict) -> dict:
    """
    Recursively merge two dictionaries, with override values taking precedence.

    When both base and override have a dict value for the same key, the dicts are
    merged recursively. For all other cases (non-dict values, or key only in one dict),
    the override value replaces the base value.

    Args:
        base: The base dictionary to merge into.
        override: The dictionary whose values take precedence.

    Returns:
        A new dictionary with merged values. Neither input dict is mutated.
    """
    result = base.copy()

    for key, value in override.items():
        if key in result and isinstance(result[key], dict) and isinstance(value, dict):
            result[key] = deep_merge(result[key], value)
        else:
            result[key] = value

    return result

unflatten

unflatten(data: dict[str, Any]) -> dict[str, Any]

Convert a flat dictionary with dotted keys to a nested structure.

Supports: - Dot notation: "foo.bar" -> {"foo": {"bar": ...}} - List indices: "items[0]" -> {"items": [...]} - Bracket keys: 'data["key"]' -> {"data": {"key": ...}}

Parameters:

Name Type Description Default
data dict[str, Any]

A flat dictionary with dotted/bracketed keys.

required

Returns:

Type Description
dict[str, Any]

A nested dictionary structure.

Raises:

Type Description
ValueError

If list indices are not contiguous (e.g., index 1 exists but index 0 is missing).

Source code in src/commons/dict_operators.py
def unflatten(data: dict[str, Any]) -> dict[str, Any]:
    """
    Convert a flat dictionary with dotted keys to a nested structure.

    Supports:
    - Dot notation: "foo.bar" -> {"foo": {"bar": ...}}
    - List indices: "items[0]" -> {"items": [...]}
    - Bracket keys: 'data["key"]' -> {"data": {"key": ...}}

    Args:
        data: A flat dictionary with dotted/bracketed keys.

    Returns:
        A nested dictionary structure.

    Raises:
        ValueError: If list indices are not contiguous (e.g., index 1 exists but index 0 is missing).
    """
    result: dict[str, Any] = {}

    for flat_key, value in data.items():
        keys = _parse_key(flat_key)
        _set_nested(result, keys, value)

    _validate_no_missing_indices(result)

    return result

flatten

flatten(
    data: dict[str, Any], prefix: str = ""
) -> dict[str, Any]

Convert a nested dictionary to a flat dictionary with dotted keys.

Inverse of unflatten().

Parameters:

Name Type Description Default
data dict[str, Any]

A nested dictionary structure.

required
prefix str

Internal prefix for recursive calls.

''

Returns:

Type Description
dict[str, Any]

A flat dictionary with dotted/bracketed keys.

Source code in src/commons/dict_operators.py
def flatten(data: dict[str, Any], prefix: str = "") -> dict[str, Any]:
    """
    Convert a nested dictionary to a flat dictionary with dotted keys.

    Inverse of unflatten().

    Args:
        data: A nested dictionary structure.
        prefix: Internal prefix for recursive calls.

    Returns:
        A flat dictionary with dotted/bracketed keys.
    """
    result: dict[str, Any] = {}

    for key, value in data.items():
        if prefix:
            if _needs_bracket_notation(key):
                new_key = f'{prefix}["{key}"]'
            else:
                new_key = f"{prefix}.{key}"
        else:
            new_key = key

        if isinstance(value, dict):
            result.update(flatten(value, new_key))
        elif isinstance(value, list):
            for i, item in enumerate(value):
                if isinstance(item, dict):
                    result.update(flatten(item, f"{new_key}[{i}]"))
                else:
                    result[f"{new_key}[{i}]"] = item
        else:
            result[new_key] = value

    return result