from collections.abc import MutableMapping, MutableSequence, Sequence from copy import copy from typing import TypeVar from . import events as e from .common import HookedContainer, MutableNesting from .sequence import HookedList T = TypeVar("T") class HookedMapping(HookedContainer[T], MutableMapping[T, MutableNesting[T]]): _data: MutableMapping[T, MutableNesting[T]] def __init__( self, hook, existing: MutableMapping[T, MutableNesting[T]], path: Sequence[int] | None = None, ): self.hook = hook self._data = existing self._path = list(path) if path is not None else [] def __getitem__(self, key: T) -> MutableNesting[T]: value = self._data[key] new_path = copy(self._path) new_path.append(key) match value: case MutableMapping() as mapping: return HookedMapping(hook=self.hook, existing=mapping, path=new_path) case MutableSequence() as seq: return HookedList(hook=self.hook, existing=seq, path=new_path) case _ as item: return item def __setitem__(self, key: T, value: MutableNesting[T]) -> None: self._data[key] = value if self.hook: self.hook(e.SetItemEvent(index=key, item=value)) def __delitem__(self, key: T) -> None: item = self._data[key] del self._data[key] if self.hook: self.hook(e.RemoveItemEvent(index=key, item=item, path=self._path))