From 17749c1a5055b9b7726c51b52821a9e7c0a88c38 Mon Sep 17 00:00:00 2001 From: Nick Papior Date: Thu, 7 May 2020 20:08:50 +0200 Subject: [PATCH] enh: added inverse operator ~ One cannot override ! (easily), but ~ is also used substantially. --- sisl/category/base.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/sisl/category/base.py b/sisl/category/base.py index fa8e959d27..0b3a4dd95f 100644 --- a/sisl/category/base.py +++ b/sisl/category/base.py @@ -140,6 +140,9 @@ def __and__(self, other): def __xor__(self, other): return XOrCategory(self, other) + def __invert__(self): + return NotCategory(self) + @set_module("sisl.category") class NullCategory(Category): @@ -167,6 +170,46 @@ def name(self): return "∅" +@set_module("sisl.category") +class NotCategory(Category): + """ A class returning the *opposite* of this class (NullCategory) if it is categorized as such """ + __slots__ = ("_cat",) + + def __init__(self, cat): + super().__init__() + if isinstance(cat, CompositeCategory): + self.set_name(f"~({cat})") + else: + self.set_name(f"~{cat}") + self._cat = cat + + def categorize(self, *args, **kwargs): + r""" Base method for queriyng whether an object is a certain category """ + cat = self._cat.categorize(*args, **kwargs) + + def check(cat): + if isinstance(cat, NullCategory): + return self + return NullCategory() + + if isinstance(cat, list): + return list(map(check, cat)) + return check(cat) + + @singledispatchmethod + def __eq__(self, other): + if isinstance(other, NotCategory): + return self._cat == other._cat + return False + + @__eq__.register(list) + @__eq__.register(tuple) + @__eq__.register(np.ndarray) + def _(self, other): + # this will call the list approach + return super().__eq__(other) + + @set_module("sisl.category") class CompositeCategory(Category): """ A composite class consisting of two categories