path in change events

This commit is contained in:
John Lancaster
2026-02-21 23:07:30 -06:00
parent 54e2febf3b
commit 842868c491
3 changed files with 13 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections.abc import MutableMapping, MutableSequence from collections.abc import Container, Iterable, MutableMapping, MutableSequence, Sized
from typing import Generic, Protocol, TypeVar from typing import Protocol, TypeVar
from . import events as e from . import events as e
@@ -13,7 +13,7 @@ class HookFunction(Protocol):
def __call__(self, event: e.ChangeEvent[T]) -> None: ... def __call__(self, event: e.ChangeEvent[T]) -> None: ...
class HookedContainer(Generic[T], ABC): class HookedContainer(ABC, Sized, Iterable[T], Container[T]):
_path: MutableSequence[int] _path: MutableSequence[int]
hook: HookFunction hook: HookFunction
@@ -35,12 +35,12 @@ class HookedContainer(Generic[T], ABC):
def __setitem__(self, s, value): def __setitem__(self, s, value):
self._data[s] = value self._data[s] = value
if self.hook: if self.hook:
self.hook(e.SetItemEvent(index=s, item=value)) self.hook(e.SetItemEvent(index=s, item=value, path=self._path))
def __delitem__(self, s): def __delitem__(self, s):
del self._data[s] item = self._data.pop(s)
if self.hook: if self.hook:
self.hook(e.RemoveItemEvent(index=s, item=self._data[s])) self.hook(e.RemoveItemEvent(index=s, item=item, path=self._path))
@abstractmethod @abstractmethod
def insert(self, index, value): ... def insert(self, index, value): ...

View File

@@ -1,3 +1,4 @@
from collections.abc import MutableSequence
from dataclasses import dataclass from dataclasses import dataclass
from typing import Generic, TypeVar from typing import Generic, TypeVar
@@ -8,6 +9,7 @@ T = TypeVar("T")
class ChangeEvent(Generic[T]): class ChangeEvent(Generic[T]):
index: int index: int
item: T item: T
path: MutableSequence[int] | None = None
@dataclass(frozen=True) @dataclass(frozen=True)

View File

@@ -24,12 +24,14 @@ class HookedList(HookedContainer[T], MutableSequence[T]):
self._path = list(path) if path is not None else [] self._path = list(path) if path is not None else []
def __getitem__(self, s): def __getitem__(self, s):
# print("Getting item:", s)
match self._data[s]: match self._data[s]:
case MutableSequence() as seq:
new_path = copy(self._path)
new_path.append(s)
return type(self)(self.hook, existing=seq, path=new_path)
case HookedContainer(_data=seq): case HookedContainer(_data=seq):
new_path = copy(self._path) new_path = copy(self._path)
new_path.append(s) new_path.append(s)
# print(new_path)
return type(self)(self.hook, existing=seq, path=new_path) return type(self)(self.hook, existing=seq, path=new_path)
case _ as item: case _ as item:
return item return item
@@ -37,4 +39,4 @@ class HookedList(HookedContainer[T], MutableSequence[T]):
def insert(self, index, value): def insert(self, index, value):
self._data.insert(index, value) self._data.insert(index, value)
if self.hook: if self.hook:
self.hook(e.AddItemEvent(index=index, item=value)) self.hook(e.AddItemEvent(index=index, item=value, path=self._path))