Source code for config_versioned.utilities

"""Utility functions for safe nested dict/list access."""


[docs] def pull_from_config(x, *keys, fail_if_none=True): """Safely retrieve a nested value from a dict or list by sequential keys. Parameters ---------- x : dict or list The top-level container to index into. *keys : str or int Sequence of keys or indices to apply in order. Use str for dict keys and int for list indices. fail_if_none : bool, default True If True, raise ValueError when the retrieved value is None. Returns ------- The value at the specified path in x. If no keys are provided, returns x unchanged. Raises ------ TypeError If a key is not str or int. KeyError If a str key is absent from its dict. IndexError If an int index is out of range for its list. ValueError If the value is None and fail_if_none is True. """ working = x for i, key in enumerate(keys): prefix = f"Issue with key #{i + 1}:" if not isinstance(key, (str, int)): raise TypeError( f"{prefix} keys must be str or int, got {type(key).__name__}" ) if isinstance(key, str): if not isinstance(working, dict) or key not in working: if not fail_if_none: return None raise KeyError(f"{prefix} '{key}' not found in the sub-dict.") working = working[key] else: if not isinstance(working, (list, tuple)) or key >= len(working): if not fail_if_none: return None length = len(working) if isinstance(working, (list, tuple)) else "N/A" raise IndexError( f"{prefix} numeric index {key} is out of range (length {length})." ) working = working[key] if fail_if_none and working is None: raise ValueError(f"{prefix} value is None.") return working