aboutsummaryrefslogtreecommitdiffstats
path: root/bsfs/graph/nodes.py
diff options
context:
space:
mode:
authorMatthias Baumgartner <dev@igsor.net>2023-01-21 23:03:50 +0100
committerMatthias Baumgartner <dev@igsor.net>2023-01-21 23:03:50 +0100
commit1392951dfc82af05e7a5999baa1c0a4fc72083b8 (patch)
treeead6f9249a8f32e5709b883e9b17c42113e80906 /bsfs/graph/nodes.py
parent04bb201c6162e81dbdefcb1cff9595180fa66917 (diff)
downloadbsfs-1392951dfc82af05e7a5999baa1c0a4fc72083b8.tar.gz
bsfs-1392951dfc82af05e7a5999baa1c0a4fc72083b8.tar.bz2
bsfs-1392951dfc82af05e7a5999baa1c0a4fc72083b8.zip
Nodes magic methods for convenience
Diffstat (limited to 'bsfs/graph/nodes.py')
-rw-r--r--bsfs/graph/nodes.py51
1 files changed, 51 insertions, 0 deletions
diff --git a/bsfs/graph/nodes.py b/bsfs/graph/nodes.py
index 18ab30d..85e5fdb 100644
--- a/bsfs/graph/nodes.py
+++ b/bsfs/graph/nodes.py
@@ -93,6 +93,57 @@ class Nodes():
"""Return the store's local schema."""
return self._backend.schema
+ def __add__(self, other: typing.Any) -> 'Nodes':
+ """Concatenate guids. Backend, user, and node type must match."""
+ if not isinstance(other, type(self)):
+ return NotImplemented
+ if self._backend != other._backend:
+ raise ValueError(other)
+ if self._user != other._user:
+ raise ValueError(other)
+ if self.node_type != other.node_type:
+ raise ValueError(other)
+ return Nodes(self._backend, self._user, self.node_type, self._guids | other._guids)
+
+ def __or__(self, other: typing.Any) -> 'Nodes':
+ """Concatenate guids. Backend, user, and node type must match."""
+ return self.__add__(other)
+
+ def __sub__(self, other: typing.Any) -> 'Nodes':
+ """Subtract guids. Backend, user, and node type must match."""
+ if not isinstance(other, type(self)):
+ return NotImplemented
+ if self._backend != other._backend:
+ raise ValueError(other)
+ if self._user != other._user:
+ raise ValueError(other)
+ if self.node_type != other.node_type:
+ raise ValueError(other)
+ return Nodes(self._backend, self._user, self.node_type, self._guids - other._guids)
+
+ def __and__(self, other: typing.Any) -> 'Nodes':
+ """Intersect guids. Backend, user, and node type must match."""
+ if not isinstance(other, type(self)):
+ return NotImplemented
+ if self._backend != other._backend:
+ raise ValueError(other)
+ if self._user != other._user:
+ raise ValueError(other)
+ if self.node_type != other.node_type:
+ raise ValueError(other)
+ return Nodes(self._backend, self._user, self.node_type, self._guids & other._guids)
+
+ def __len__(self) -> int:
+ """Return the number of guids."""
+ return len(self._guids)
+
+ def __iter__(self) -> typing.Iterator['Nodes']:
+ """Iterate over individual guids. Returns `Nodes` instances."""
+ return iter(
+ Nodes(self._backend, self._user, self.node_type, {guid})
+ for guid in self._guids
+ )
+
def __getattr__(self, name: str):
try:
return super().__getattr__(name) # type: ignore [misc] # parent has no getattr