From: Frank Brehm Date: Thu, 19 Nov 2020 17:00:23 +0000 (+0100) Subject: Adding lib/ldap_migration/istringset.py X-Git-Url: https://git.uhu-banane.net/?a=commitdiff_plain;h=52282fcb54e763eabf13e892ef53ad0d6193d019;p=pixelpark%2Fldap-migration.git Adding lib/ldap_migration/istringset.py --- diff --git a/lib/ldap_migration/istringset.py b/lib/ldap_migration/istringset.py index 5855d12..302becd 100644 --- a/lib/ldap_migration/istringset.py +++ b/lib/ldap_migration/istringset.py @@ -10,7 +10,6 @@ from __future__ import absolute_import # Standard module import logging -import copy try: from collections.abc import MutableSet @@ -20,9 +19,7 @@ except ImportError: # Third party modules # Own modules -from fb_tools.common import pp from fb_tools.errors import FbError -from fb_tools.obj import FbBaseObject __version__ = '0.1.0' @@ -30,11 +27,13 @@ LOG = logging.getLogger(__name__) # ============================================================================= class WrongItemTypeError(TypeError, FbError): + """Exeception class for the case, that a given parameter ist not of type str.""" # ------------------------------------------------------------------------- def __init__(self, item): self.item = item + super(WrongItemTypeError, self).__init__() # ------------------------------------------------------------------------- def __str__(self): @@ -45,11 +44,14 @@ class WrongItemTypeError(TypeError, FbError): # ============================================================================= class WrongCompareSetClassError(TypeError, FbError): + """Exeception class for the case, that a given class ist not of an + instance of CaseInsensitiveStringSet.""" # ------------------------------------------------------------------------- def __init__(self, other): self.other_class = other.__class__.__name__ + super(WrongCompareSetClassError, self).__init__() # ------------------------------------------------------------------------- def __str__(self): @@ -71,15 +73,14 @@ class CaseInsensitiveStringSet(MutableSet): # ------------------------------------------------------------------------- def __init__(self, iterable): - self._items = [] + self._items = {} for item in iterable: if not isinstance(item, str): raise WrongItemTypeError(item) - if item not in self: - self._items.append(item) + self.add(item) # ------------------------------------------------------------------------- # Mandatory methods (ABC methods) @@ -87,68 +88,44 @@ class CaseInsensitiveStringSet(MutableSet): # ------------------------------------------------------------------------- def __iter__(self): - return iter(self._items) + for key in sorted(self._items.keys()): + yield self._items[key] # ------------------------------------------------------------------------- def __contains__(self, value): + """ The 'in' operator.""" if not isinstance(value, str): raise WrongItemTypeError(value) - for item in self._items: - if item.lower() == value.lower(): - return True - - return value in self.elements + ival = value.lower() + if ival in self._items: + return True + return False # ------------------------------------------------------------------------- def __len__(self): return len(self._items) - # ------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def add(self, value): if not isinstance(value, str): raise WrongItemTypeError(value) - if value in self: - - index = 0 - for item in self._items: - if item.lower() == value.lower(): - if item != value: - self._items[index] = value - break - index += 1 - - else: - self._items.append(value) + ival = value.lower() + self._items[ival] = value # ------------------------------------------------------------------------- def discard(self, value): - index = 0 - for item in self._items: - if item.lower() == value.lower(): - del self._items[index] - break - index += 1 + ival = value.lower() + if ival in self._items: + del self._items[ival] # ------------------------------------------------------------------------- # Nice to have methods - # ------------------------------------------------------------------------- - def isdisjoint(self, other): - - if not isinstance(other, CaseInsensitiveStringSet): - raise WrongCompareSetClassError(other) - - for item in self._items: - if item in other: - return False - - return True - # ------------------------------------------------------------------------- def issubset(self, other): @@ -163,6 +140,7 @@ class CaseInsensitiveStringSet(MutableSet): # ------------------------------------------------------------------------- def __le__(self, other): + """The '<=' operator.""" if not isinstance(other, CaseInsensitiveStringSet): raise WrongCompareSetClassError(other) @@ -171,6 +149,7 @@ class CaseInsensitiveStringSet(MutableSet): # ------------------------------------------------------------------------- def __eq__(self, other): + """The '==' operator.""" if not isinstance(other, CaseInsensitiveStringSet): raise WrongCompareSetClassError(other) @@ -186,6 +165,7 @@ class CaseInsensitiveStringSet(MutableSet): # ------------------------------------------------------------------------- def __ne__(self, other): + """The '!=' operator.""" if not isinstance(other, CaseInsensitiveStringSet): raise WrongCompareSetClassError(other) @@ -196,6 +176,7 @@ class CaseInsensitiveStringSet(MutableSet): # ------------------------------------------------------------------------- def __lt__(self, other): + """The '<' operator.""" if not isinstance(other, CaseInsensitiveStringSet): raise WrongCompareSetClassError(other) @@ -209,6 +190,311 @@ class CaseInsensitiveStringSet(MutableSet): return True return False + # ------------------------------------------------------------------------- + def __gt__(self, other): + """The '>' operator.""" + + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + if self.__le__(other): + return False + return True + + # ------------------------------------------------------------------------- + def __ge__(self, other): + """The '>=' operator.""" + + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + if self.__lt__(other): + return False + return True + + # ------------------------------------------------------------------------- + def __copy__(self): + + empty = [] + new_set = self.__class__(empty) + for item in self: + new_set.add(item) + + return new_set + + # ------------------------------------------------------------------------- + def copy(self): + return self.__copy__() + + # ------------------------------------------------------------------------- + def values(self): + + ret = [] + for item in self: + ret.append(item) + return ret + + # ------------------------------------------------------------------------- + def __str__(self): + + if len(self) == 0: + return "{}()".format(self.__class__.__name__) + + ret = "{}(".format(self.__class__.__name__) + ret += ', '.join(map(lambda x: "{!r}".format(x), self.values())) + ret += ')' + + return ret + + # ------------------------------------------------------------------------- + def __repr__(self): + return str(self) + + # ------------------------------------------------------------------------- + def union(self, *others): + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + new_set = self.__copy__() + for other in others: + for item in other: + if item not in new_set: + new_set.add(item) + + return new_set + + # ------------------------------------------------------------------------- + def __or__(self, *others): + """The '|' operator.""" + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + return self.union(*others) + + # ------------------------------------------------------------------------- + def intersection(self, *others): + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + empty = [] + new_set = self.__class__(empty) + for item in self: + do_add = True + for other in others: + if item not in other: + do_add = False + if do_add: + new_set.add(item) + + return new_set + + # ------------------------------------------------------------------------- + def __and__(self, *others): + """The '&' operator.""" + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + return self.intersection(*others) + + # ------------------------------------------------------------------------- + def difference(self, *others): + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + empty = [] + new_set = self.__class__(empty) + for item in self: + do_add = True + for other in others: + if item in other: + do_add = False + if do_add: + new_set.add(item) + + return new_set + + # ------------------------------------------------------------------------- + def __sub__(self, *others): + """The '-' operator.""" + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + return self.difference(*others) + + # ------------------------------------------------------------------------- + def symmetric_difference(self, other): + + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + empty = [] + new_set = self.__class__(empty) + + for item in self: + if item not in other: + new_set.add(item) + + for item in other: + if item not in self: + new_set.add(item) + + return new_set + + # ------------------------------------------------------------------------- + def __xor__(self, other): + """The '^' operator.""" + + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + return self.symmetric_difference(other) + + # ------------------------------------------------------------------------- + def isdisjoint(self, other): + + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + for item in self: + if item in other: + return False + + for item in other: + if item in self: + return False + + return True + + # ------------------------------------------------------------------------- + def update(self, *others): + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + for other in others: + for item in other: + if item not in self: + self.add(item) + + # ------------------------------------------------------------------------- + def __ior__(self, *others): + """The '|=' operator.""" + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + self.update(*others) + + # ------------------------------------------------------------------------- + def intersection_update(self, *others): + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + for item in self: + for other in others: + if item not in other: + self.discard(item) + break + + # ------------------------------------------------------------------------- + def __iand__(self, *others): + """The '&=' operator.""" + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + self.intersection_update(*others) + + # ------------------------------------------------------------------------- + def difference_update(self, *others): + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + for item in self: + for other in others: + if item in other: + self.discard(item) + break + + # ------------------------------------------------------------------------- + def __isub__(self, *others): + """The '-=' operator.""" + + for other in others: + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + self.difference_update(*others) + + # ------------------------------------------------------------------------- + def symmetric_difference_update(self, other): + + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + for item in self: + if item in other: + self.discard(item) + + for item in other: + if item not in self: + self.add(item) + + # ------------------------------------------------------------------------- + def __ixor__(self, other): + """The '|=' operator.""" + + if not isinstance(other, CaseInsensitiveStringSet): + raise WrongCompareSetClassError(other) + + self.symmetric_difference_update(other) + + # ------------------------------------------------------------------------- + def remove(self, value): + + ival = value.lower() + if ival in self._items: + del self._items[ival] + return + + raise KeyError(value) + + # ------------------------------------------------------------------------- + def pop(self): + + if len(self) == 0: + raise IndexError("pop() from empty list") + + key = self._items.keys()[0] + value = self._items[key] + del self._items[key] + + return value + + # ------------------------------------------------------------------------- + def clear(self): + + self._items = {} + # ============================================================================= if __name__ == "__main__":