working mapping?

This commit is contained in:
John Lancaster
2026-02-22 17:48:27 -06:00
parent 7f4ed3a4b2
commit 70fa9ede75

View File

@@ -1,9 +1,8 @@
from collections.abc import MutableMapping, Sequence
from copy import copy
from collections.abc import MutableMapping, MutableSequence
from typing import TypeVar
from . import events as e
from .container import HookedContainer, MutableNesting
from .container import HookedContainer, HookFunction, MutableNesting
T = TypeVar("T")
@@ -13,33 +12,50 @@ class HookedMapping(HookedContainer[T], MutableMapping[T, MutableNesting[T]]):
def __init__(
self,
hook,
existing: MutableMapping[T, MutableNesting[T]],
path: Sequence[int] | None = None,
hook: HookFunction | None = None,
path: MutableSequence[int] | None = None,
):
self.hook = hook
match existing:
case HookedMapping(_data=seq):
self._data = seq
case MutableMapping() as seq:
self._data = seq
case _ as it:
self._data = dict(it)
self._data = existing
self._path = list(path) if path is not None else []
# MutableMapping Methods
def __iter__(self):
return iter(self._data)
def insert(self, key: T, value: MutableNesting[T]) -> None:
self._data[key] = value
if self.hook:
self.hook(e.AddItemEvent(index=key, item=value, path=self.new_path(key)))
# HookedContainer methods
def __getitem__(self, key: T) -> MutableNesting[T]:
value = self._data[key]
new_path = copy(self._path)
new_path.append(key)
value = self._data.get(key, {})
match value:
case HookedMapping(_data=seq):
return type(self)(seq, hook=self.hook, path=self.new_path(key))
case MutableMapping() as mapping:
return HookedMapping(mapping, self.hook, path=new_path)
case HookedContainer() as seq:
return type(self)(seq, self.hook, path=new_path)
return HookedMapping(mapping, hook=self.hook, path=self.new_path(key))
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))
self.hook(e.SetItemEvent(index=key, item=value, path=self.new_path(key)))
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))
self.hook(e.RemoveItemEvent(index=key, item=item, path=self.new_path(key)))