remove blist sortedset as soft dependency
PYTHON-385
This commit is contained in:
@@ -485,210 +485,238 @@ class WeakSet(object):
|
||||
def isdisjoint(self, other):
|
||||
return len(self.intersection(other)) == 0
|
||||
|
||||
try:
|
||||
from blist import sortedset
|
||||
except ImportError:
|
||||
|
||||
from bisect import bisect_left
|
||||
from bisect import bisect_left
|
||||
|
||||
class sortedset(object):
|
||||
'''
|
||||
A sorted set based on sorted list
|
||||
|
||||
This set is used in place of blist.sortedset in Python environments
|
||||
where blist module/extension is not available.
|
||||
class SortedSet(object):
|
||||
'''
|
||||
A sorted set based on sorted list
|
||||
|
||||
A sorted set implementation is used in this case because it does not
|
||||
require its elements to be immutable/hashable.
|
||||
A sorted set implementation is used in this case because it does not
|
||||
require its elements to be immutable/hashable.
|
||||
|
||||
#Not implemented: update functions, inplace operators
|
||||
#Not implemented: update functions, inplace operators
|
||||
'''
|
||||
|
||||
'''
|
||||
def __init__(self, iterable=()):
|
||||
self._items = []
|
||||
self.update(iterable)
|
||||
|
||||
def __init__(self, iterable=()):
|
||||
self._items = []
|
||||
self.update(iterable)
|
||||
def __len__(self):
|
||||
return len(self._items)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._items)
|
||||
def __getitem__(self, i):
|
||||
return self._items[i]
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self._items[i]
|
||||
def __iter__(self):
|
||||
return iter(self._items)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._items)
|
||||
def __reversed__(self):
|
||||
return reversed(self._items)
|
||||
|
||||
def __reversed__(self):
|
||||
return reversed(self._items)
|
||||
def __repr__(self):
|
||||
return '%s(%r)' % (
|
||||
self.__class__.__name__,
|
||||
self._items)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%r)' % (
|
||||
self.__class__.__name__,
|
||||
self._items)
|
||||
def __reduce__(self):
|
||||
return self.__class__, (self._items,)
|
||||
|
||||
def __reduce__(self):
|
||||
return self.__class__, (self._items,)
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self._items == other._items
|
||||
else:
|
||||
try:
|
||||
return len(other) == len(self._items) and all(item in self for item in other)
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self._items == other._items
|
||||
else:
|
||||
if not isinstance(other, set):
|
||||
return False
|
||||
def __ne__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self._items != other._items
|
||||
else:
|
||||
try:
|
||||
return len(other) != len(self._items) or any(item not in self for item in other)
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
return len(other) == len(self._items) and all(item in other for item in self._items)
|
||||
def __le__(self, other):
|
||||
return self.issubset(other)
|
||||
|
||||
def __ne__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self._items != other._items
|
||||
else:
|
||||
if not isinstance(other, set):
|
||||
return True
|
||||
def __lt__(self, other):
|
||||
return len(other) > len(self._items) and self.issubset(other)
|
||||
|
||||
return len(other) != len(self._items) or any(item not in other for item in self._items)
|
||||
def __ge__(self, other):
|
||||
return self.issuperset(other)
|
||||
|
||||
def __le__(self, other):
|
||||
return self.issubset(other)
|
||||
def __gt__(self, other):
|
||||
return len(self._items) > len(other) and self.issuperset(other)
|
||||
|
||||
def __lt__(self, other):
|
||||
return len(other) > len(self._items) and self.issubset(other)
|
||||
def __and__(self, other):
|
||||
return self._intersect(other)
|
||||
__rand__ = __and__
|
||||
|
||||
def __ge__(self, other):
|
||||
return self.issuperset(other)
|
||||
def __iand__(self, other):
|
||||
isect = self._intersect(other)
|
||||
self._items = isect._items
|
||||
return self
|
||||
|
||||
def __gt__(self, other):
|
||||
return len(self._items) > len(other) and self.issuperset(other)
|
||||
def __or__(self, other):
|
||||
return self.union(other)
|
||||
__ror__ = __or__
|
||||
|
||||
def __and__(self, other):
|
||||
return self._intersect(other)
|
||||
def __ior__(self, other):
|
||||
union = self.union(other)
|
||||
self._items = union._items
|
||||
return self
|
||||
|
||||
def __or__(self, other):
|
||||
return self.union(other)
|
||||
def __sub__(self, other):
|
||||
return self._diff(other)
|
||||
|
||||
def __sub__(self, other):
|
||||
return self._diff(other)
|
||||
def __rsub__(self, other):
|
||||
return sortedset(other) - self
|
||||
|
||||
def __xor__(self, other):
|
||||
return self.symmetric_difference(other)
|
||||
def __isub__(self, other):
|
||||
diff = self._diff(other)
|
||||
self._items = diff._items
|
||||
return self
|
||||
|
||||
def __contains__(self, item):
|
||||
i = bisect_left(self._items, item)
|
||||
return i < len(self._items) and self._items[i] == item
|
||||
def __xor__(self, other):
|
||||
return self.symmetric_difference(other)
|
||||
__rxor__ = __xor__
|
||||
|
||||
def add(self, item):
|
||||
i = bisect_left(self._items, item)
|
||||
if i < len(self._items):
|
||||
if self._items[i] != item:
|
||||
self._items.insert(i, item)
|
||||
else:
|
||||
self._items.append(item)
|
||||
def __ixor__(self, other):
|
||||
sym_diff = self.symmetric_difference(other)
|
||||
self._items = sym_diff._items
|
||||
return self
|
||||
|
||||
def update(self, iterable):
|
||||
for i in iterable:
|
||||
self.add(i)
|
||||
def __contains__(self, item):
|
||||
i = bisect_left(self._items, item)
|
||||
return i < len(self._items) and self._items[i] == item
|
||||
|
||||
def clear(self):
|
||||
del self._items[:]
|
||||
def __delitem__(self, i):
|
||||
del self._items[i]
|
||||
|
||||
def copy(self):
|
||||
new = sortedset()
|
||||
new._items = list(self._items)
|
||||
return new
|
||||
def __delslice__(self, i, j):
|
||||
del self._items[i:j]
|
||||
|
||||
def isdisjoint(self, other):
|
||||
return len(self._intersect(other)) == 0
|
||||
def add(self, item):
|
||||
i = bisect_left(self._items, item)
|
||||
if i < len(self._items):
|
||||
if self._items[i] != item:
|
||||
self._items.insert(i, item)
|
||||
else:
|
||||
self._items.append(item)
|
||||
|
||||
def issubset(self, other):
|
||||
return len(self._intersect(other)) == len(self._items)
|
||||
def update(self, iterable):
|
||||
for i in iterable:
|
||||
self.add(i)
|
||||
|
||||
def issuperset(self, other):
|
||||
return len(self._intersect(other)) == len(other)
|
||||
def clear(self):
|
||||
del self._items[:]
|
||||
|
||||
def pop(self):
|
||||
if not self._items:
|
||||
raise KeyError("pop from empty set")
|
||||
return self._items.pop()
|
||||
def copy(self):
|
||||
new = sortedset()
|
||||
new._items = list(self._items)
|
||||
return new
|
||||
|
||||
def remove(self, item):
|
||||
i = bisect_left(self._items, item)
|
||||
if i < len(self._items):
|
||||
if self._items[i] == item:
|
||||
self._items.pop(i)
|
||||
return
|
||||
raise KeyError('%r' % item)
|
||||
def isdisjoint(self, other):
|
||||
return len(self._intersect(other)) == 0
|
||||
|
||||
def union(self, *others):
|
||||
union = sortedset()
|
||||
union._items = list(self._items)
|
||||
for other in others:
|
||||
if isinstance(other, self.__class__):
|
||||
i = 0
|
||||
for item in other._items:
|
||||
i = bisect_left(union._items, item, i)
|
||||
if i < len(union._items):
|
||||
if item != union._items[i]:
|
||||
union._items.insert(i, item)
|
||||
else:
|
||||
union._items.append(item)
|
||||
else:
|
||||
for item in other:
|
||||
union.add(item)
|
||||
return union
|
||||
def issubset(self, other):
|
||||
return len(self._intersect(other)) == len(self._items)
|
||||
|
||||
def intersection(self, *others):
|
||||
isect = self.copy()
|
||||
for other in others:
|
||||
isect = isect._intersect(other)
|
||||
if not isect:
|
||||
break
|
||||
return isect
|
||||
def issuperset(self, other):
|
||||
return len(self._intersect(other)) == len(other)
|
||||
|
||||
def difference(self, *others):
|
||||
diff = self.copy()
|
||||
for other in others:
|
||||
diff = diff._diff(other)
|
||||
if not diff:
|
||||
break
|
||||
return diff
|
||||
def pop(self):
|
||||
if not self._items:
|
||||
raise KeyError("pop from empty set")
|
||||
return self._items.pop()
|
||||
|
||||
def symmetric_difference(self, other):
|
||||
diff_self_other = self._diff(other)
|
||||
diff_other_self = other.difference(self)
|
||||
return diff_self_other.union(diff_other_self)
|
||||
def remove(self, item):
|
||||
i = bisect_left(self._items, item)
|
||||
if i < len(self._items):
|
||||
if self._items[i] == item:
|
||||
self._items.pop(i)
|
||||
return
|
||||
raise KeyError('%r' % item)
|
||||
|
||||
def _diff(self, other):
|
||||
diff = sortedset()
|
||||
def union(self, *others):
|
||||
union = sortedset()
|
||||
union._items = list(self._items)
|
||||
for other in others:
|
||||
if isinstance(other, self.__class__):
|
||||
i = 0
|
||||
for item in self._items:
|
||||
i = bisect_left(other._items, item, i)
|
||||
if i < len(other._items):
|
||||
if item != other._items[i]:
|
||||
diff._items.append(item)
|
||||
for item in other._items:
|
||||
i = bisect_left(union._items, item, i)
|
||||
if i < len(union._items):
|
||||
if item != union._items[i]:
|
||||
union._items.insert(i, item)
|
||||
else:
|
||||
union._items.append(item)
|
||||
else:
|
||||
for item in other:
|
||||
union.add(item)
|
||||
return union
|
||||
|
||||
def intersection(self, *others):
|
||||
isect = self.copy()
|
||||
for other in others:
|
||||
isect = isect._intersect(other)
|
||||
if not isect:
|
||||
break
|
||||
return isect
|
||||
|
||||
def difference(self, *others):
|
||||
diff = self.copy()
|
||||
for other in others:
|
||||
diff = diff._diff(other)
|
||||
if not diff:
|
||||
break
|
||||
return diff
|
||||
|
||||
def symmetric_difference(self, other):
|
||||
diff_self_other = self._diff(other)
|
||||
diff_other_self = other.difference(self)
|
||||
return diff_self_other.union(diff_other_self)
|
||||
|
||||
def _diff(self, other):
|
||||
diff = sortedset()
|
||||
if isinstance(other, self.__class__):
|
||||
i = 0
|
||||
for item in self._items:
|
||||
i = bisect_left(other._items, item, i)
|
||||
if i < len(other._items):
|
||||
if item != other._items[i]:
|
||||
diff._items.append(item)
|
||||
else:
|
||||
for item in self._items:
|
||||
if item not in other:
|
||||
diff.add(item)
|
||||
return diff
|
||||
else:
|
||||
diff._items.append(item)
|
||||
else:
|
||||
for item in self._items:
|
||||
if item not in other:
|
||||
diff.add(item)
|
||||
return diff
|
||||
|
||||
def _intersect(self, other):
|
||||
isect = sortedset()
|
||||
if isinstance(other, self.__class__):
|
||||
i = 0
|
||||
for item in self._items:
|
||||
i = bisect_left(other._items, item, i)
|
||||
if i < len(other._items):
|
||||
if item == other._items[i]:
|
||||
isect._items.append(item)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
for item in self._items:
|
||||
if item in other:
|
||||
isect.add(item)
|
||||
return isect
|
||||
def _intersect(self, other):
|
||||
isect = sortedset()
|
||||
if isinstance(other, self.__class__):
|
||||
i = 0
|
||||
for item in self._items:
|
||||
i = bisect_left(other._items, item, i)
|
||||
if i < len(other._items):
|
||||
if item == other._items[i]:
|
||||
isect._items.append(item)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
for item in self._items:
|
||||
if item in other:
|
||||
isect.add(item)
|
||||
return isect
|
||||
|
||||
sortedset = SortedSet # backwards-compatibility
|
||||
|
||||
|
||||
from collections import Mapping
|
||||
|
||||
Reference in New Issue
Block a user