From 842868c4914df104f5bc335f3349845c0b27f6be Mon Sep 17 00:00:00 2001 From: John Lancaster <32917998+jsl12@users.noreply.github.com> Date: Sat, 21 Feb 2026 23:07:30 -0600 Subject: [PATCH] path in change events --- src/hooked_containers/common.py | 12 ++++++------ src/hooked_containers/events.py | 2 ++ src/hooked_containers/sequence.py | 8 +++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/hooked_containers/common.py b/src/hooked_containers/common.py index cb5b8af..99bdc90 100644 --- a/src/hooked_containers/common.py +++ b/src/hooked_containers/common.py @@ -1,6 +1,6 @@ from abc import ABC, abstractmethod -from collections.abc import MutableMapping, MutableSequence -from typing import Generic, Protocol, TypeVar +from collections.abc import Container, Iterable, MutableMapping, MutableSequence, Sized +from typing import Protocol, TypeVar from . import events as e @@ -13,7 +13,7 @@ class HookFunction(Protocol): def __call__(self, event: e.ChangeEvent[T]) -> None: ... -class HookedContainer(Generic[T], ABC): +class HookedContainer(ABC, Sized, Iterable[T], Container[T]): _path: MutableSequence[int] hook: HookFunction @@ -35,12 +35,12 @@ class HookedContainer(Generic[T], ABC): def __setitem__(self, s, value): self._data[s] = value 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): - del self._data[s] + item = self._data.pop(s) 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 def insert(self, index, value): ... diff --git a/src/hooked_containers/events.py b/src/hooked_containers/events.py index 3568f5c..e4536db 100644 --- a/src/hooked_containers/events.py +++ b/src/hooked_containers/events.py @@ -1,3 +1,4 @@ +from collections.abc import MutableSequence from dataclasses import dataclass from typing import Generic, TypeVar @@ -8,6 +9,7 @@ T = TypeVar("T") class ChangeEvent(Generic[T]): index: int item: T + path: MutableSequence[int] | None = None @dataclass(frozen=True) diff --git a/src/hooked_containers/sequence.py b/src/hooked_containers/sequence.py index 624bf5c..ef51c40 100644 --- a/src/hooked_containers/sequence.py +++ b/src/hooked_containers/sequence.py @@ -24,12 +24,14 @@ class HookedList(HookedContainer[T], MutableSequence[T]): self._path = list(path) if path is not None else [] def __getitem__(self, s): - # print("Getting item:", 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): new_path = copy(self._path) new_path.append(s) - # print(new_path) return type(self)(self.hook, existing=seq, path=new_path) case _ as item: return item @@ -37,4 +39,4 @@ class HookedList(HookedContainer[T], MutableSequence[T]): def insert(self, index, value): self._data.insert(index, value) if self.hook: - self.hook(e.AddItemEvent(index=index, item=value)) + self.hook(e.AddItemEvent(index=index, item=value, path=self._path))