From 317524fad2306750780cc17370d41878c9b1e70b Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Wed, 24 Dec 2025 00:05:59 +0100 Subject: [PATCH 1/3] chore:Experiment with faster implementation --- src/psygnal/containers/_evented_set.py | 28 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/psygnal/containers/_evented_set.py b/src/psygnal/containers/_evented_set.py index 85e22e29..18d9a427 100644 --- a/src/psygnal/containers/_evented_set.py +++ b/src/psygnal/containers/_evented_set.py @@ -48,8 +48,12 @@ def add(self, item: _T) -> None: def update(self, *others: Iterable[_T]) -> None: """Update this set with the union of this set and others.""" - for i in chain(*others): - self.add(i) + other: set[_T] = set() + other.update(*others) + other -= self._data + + self._data.update(other) + self._post_add_many_hook(tuple(other)) def discard(self, item: _T) -> None: """Remove an element from a set if it is a member. @@ -65,7 +69,7 @@ def clear(self) -> None: _item = self._pre_clear_hook() if not isinstance(_item, BailType): self._do_clear() - self._post_clear_hook(_item) + self._post_remove_many_hook(_item) def __contains__(self, value: object) -> bool: """Return True if value is in set.""" @@ -90,6 +94,8 @@ def _pre_add_hook(self, item: _T) -> _T | BailType: def _post_add_hook(self, item: _T) -> None: ... + def _post_add_many_hook(self, item: tuple[_T, ...]) -> None: ... + def _pre_discard_hook(self, item: _T) -> _T | BailType: return item # pragma: no cover @@ -98,7 +104,7 @@ def _post_discard_hook(self, item: _T) -> None: ... def _pre_clear_hook(self) -> tuple[_T, ...] | BailType: return tuple(self) # pragma: no cover - def _post_clear_hook(self, item: tuple[_T, ...]) -> None: ... + def _post_remove_many_hook(self, item: tuple[_T, ...]) -> None: ... def _do_add(self, item: _T) -> None: self._data.add(item) @@ -135,15 +141,14 @@ def intersection(self, *s: Iterable[_T]) -> Self: (i.e. all elements that are in both sets.) """ - other = set.intersection(*(set(x) for x in s)) - return self.__class__(i for i in self if i in other) + return self.__class__(self._data.intersection(*s)) def intersection_update(self, *s: Iterable[_T]) -> None: """Update this set with the intersection of itself and another.""" other = set.intersection(*(set(x) for x in s)) - for i in tuple(self): - if i not in other: - self.discard(i) + drop_data = self._data.difference(other) + self._data.difference_update(drop_data) + self._post_remove_many_hook(tuple(drop_data)) def issubset(self, __s: Iterable[Any]) -> bool: """Report whether another set contains this set.""" @@ -322,6 +327,9 @@ def _pre_add_hook(self, item: _T) -> _T | BailType: def _post_add_hook(self, item: _T) -> None: self._emit_change((item,), ()) + def _post_add_many_hook(self, item: tuple[_T, ...]) -> None: + self._emit_change(item, ()) + def _pre_discard_hook(self, item: _T) -> _T | BailType: return BAIL if item not in self else item @@ -331,7 +339,7 @@ def _post_discard_hook(self, item: _T) -> None: def _pre_clear_hook(self) -> tuple[_T, ...] | BailType: return BAIL if len(self) == 0 else tuple(self) - def _post_clear_hook(self, item: tuple[_T, ...]) -> None: + def _post_remove_many_hook(self, item: tuple[_T, ...]) -> None: self._emit_change((), item) def _emit_change(self, added: tuple[_T, ...], removed: tuple[_T, ...]) -> None: From 68ab3660dfe4a046572235dda70ec07dd40d7bee Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Wed, 24 Dec 2025 00:26:03 +0100 Subject: [PATCH 2/3] limit mypy --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d3b3b350..c0612bed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,7 +103,7 @@ enable-by-default = false require-runtime-dependencies = true dependencies = [ "hatch-mypyc>=0.13.0", - "mypy", + "mypy<1.19.0", "mypy_extensions >=0.4.2", "pydantic!=2.10.0", # typing error in v2.10 prevents mypyc from working "types-attrs", From cd8b242cc482e1ad5ff387a0434d923ba545ef95 Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Wed, 24 Dec 2025 01:52:25 +0100 Subject: [PATCH 3/3] unpin mypy --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c0612bed..d3b3b350 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,7 +103,7 @@ enable-by-default = false require-runtime-dependencies = true dependencies = [ "hatch-mypyc>=0.13.0", - "mypy<1.19.0", + "mypy", "mypy_extensions >=0.4.2", "pydantic!=2.10.0", # typing error in v2.10 prevents mypyc from working "types-attrs",