from types import MappingProxyType from collections.abc import Iterable, Mapping, Sequence, Set from typing import Any def to_deep_immutable(obj: Any): """Recursively convert mutable containers to immutable equivalents.""" # Handle mappings (dict-like). if isinstance(obj, Mapping): return MappingProxyType({to_deep_immutable(key): to_deep_immutable(value) for key, value in obj.items()}) # Handle sets. if isinstance(obj, Set): return frozenset(to_deep_immutable(item) for item in obj) # Handle sequences (list/tuple-like). if isinstance(obj, (Iterable, Sequence)) and not isinstance(obj, (str, bytes)): return tuple(to_deep_immutable(item) for item in obj) # Return anything else as-is. return obj