347 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			347 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Python
		
	
	
	
"""
 | 
						|
Convenience interface for NSSet/NSMutableSet
 | 
						|
"""
 | 
						|
__all__ = ()
 | 
						|
 | 
						|
import collections.abc
 | 
						|
 | 
						|
from objc._convenience import addConvenienceForClass, container_unwrap, container_wrap
 | 
						|
from objc._objc import lookUpClass
 | 
						|
 | 
						|
NSSet = lookUpClass("NSSet")
 | 
						|
NSMutableSet = lookUpClass("NSMutableSet")
 | 
						|
 | 
						|
collections.abc.Set.register(NSSet)
 | 
						|
collections.abc.MutableSet.register(NSMutableSet)
 | 
						|
 | 
						|
 | 
						|
def nsset_isdisjoint(self, other):
 | 
						|
    if not hasattr(other, "__contains__"):
 | 
						|
        other = list(other)
 | 
						|
 | 
						|
    for item in self:
 | 
						|
        if item in other:
 | 
						|
            return False
 | 
						|
    return True
 | 
						|
 | 
						|
 | 
						|
def nsset_union(self, *other):
 | 
						|
    result = NSMutableSet()
 | 
						|
    result.unionSet_(self)
 | 
						|
    for val in other:
 | 
						|
        if isinstance(val, collections.abc.Set):
 | 
						|
            result.unionSet_(val)
 | 
						|
        else:
 | 
						|
            result.unionSet_(set(val))
 | 
						|
    return result
 | 
						|
 | 
						|
 | 
						|
def nsset_intersection(self, *others):
 | 
						|
    if len(others) == 0:
 | 
						|
        return self.mutableCopy()
 | 
						|
 | 
						|
    others = [o if hasattr(o, "__contains__") else list(o) for o in others]
 | 
						|
 | 
						|
    result = NSMutableSet()
 | 
						|
    for item in self:
 | 
						|
        for o in others:
 | 
						|
            if item not in o:
 | 
						|
                break
 | 
						|
        else:
 | 
						|
            result.add(item)
 | 
						|
    return result
 | 
						|
 | 
						|
 | 
						|
def nsset_difference(self, *others):
 | 
						|
    result = self.mutableCopy()
 | 
						|
 | 
						|
    for value in others:
 | 
						|
        if isinstance(value, collections.abc.Set):
 | 
						|
            result.minusSet_(value)
 | 
						|
        else:
 | 
						|
            result.minusSet_(set(value))
 | 
						|
 | 
						|
    return result
 | 
						|
 | 
						|
 | 
						|
def nsset_symmetric_difference(self, other):
 | 
						|
    result = NSMutableSet()
 | 
						|
    if not hasattr(other, "__contains__"):
 | 
						|
        other = list(other)
 | 
						|
    for item in iter(self):
 | 
						|
        if item not in other:
 | 
						|
            result.add(item)
 | 
						|
    for item in other:
 | 
						|
        if item not in self:
 | 
						|
            result.add(item)
 | 
						|
    return result
 | 
						|
 | 
						|
 | 
						|
def nsset__contains__(self, value):
 | 
						|
    hash(value)  # Force error for non-hashable values
 | 
						|
    return self.containsObject_(value)
 | 
						|
 | 
						|
 | 
						|
def nsset__or__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError("NSSet|value where value is not a set")
 | 
						|
    return nsset_union(self, other)
 | 
						|
 | 
						|
 | 
						|
def nsset__ror__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError("value|NSSet where value is not a set")
 | 
						|
    return nsset_union(other, self)
 | 
						|
 | 
						|
 | 
						|
def nsset__and__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError("NSSet&value where value is not a set")
 | 
						|
    return nsset_intersection(self, other)
 | 
						|
 | 
						|
 | 
						|
def nsset__rand__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError("value&NSSet where value is not a set")
 | 
						|
    return nsset_intersection(other, self)
 | 
						|
 | 
						|
 | 
						|
def nsset__sub__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError("NSSet-value where value is not a set")
 | 
						|
    return nsset_difference(self, other)
 | 
						|
 | 
						|
 | 
						|
def nsset__rsub__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError("NSSet-value where value is not a set")
 | 
						|
    return nsset_difference(NSMutableSet(other), self)
 | 
						|
 | 
						|
 | 
						|
def nsset__xor__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError("NSSet-value where value is not a set")
 | 
						|
    return nsset_symmetric_difference(other, self)
 | 
						|
 | 
						|
 | 
						|
def nsset_issubset(self, other):
 | 
						|
    if isinstance(other, collections.abc.Set):
 | 
						|
        return self.isSubsetOfSet_(other)
 | 
						|
 | 
						|
    else:
 | 
						|
        return self.isSubsetOfSet_(set(other))
 | 
						|
 | 
						|
 | 
						|
def nsset__le__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError()
 | 
						|
    return nsset_issubset(self, other)
 | 
						|
 | 
						|
 | 
						|
def nsset__eq__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        return False
 | 
						|
 | 
						|
    return self.isEqualToSet_(other)
 | 
						|
 | 
						|
 | 
						|
def nsset__ne__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        return True
 | 
						|
 | 
						|
    return not self.isEqualToSet_(other)
 | 
						|
 | 
						|
 | 
						|
def nsset__lt__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError()
 | 
						|
 | 
						|
    return (self <= other) and (self != other)
 | 
						|
 | 
						|
 | 
						|
def nsset_issuperset(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        other = set(other)
 | 
						|
 | 
						|
    for item in other:
 | 
						|
        if item not in self:
 | 
						|
            return False
 | 
						|
 | 
						|
    return True
 | 
						|
 | 
						|
 | 
						|
def nsset__ge__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError()
 | 
						|
    return nsset_issuperset(self, other)
 | 
						|
 | 
						|
 | 
						|
def nsset__gt__(self, other):
 | 
						|
    if not isinstance(other, collections.abc.Set):
 | 
						|
        raise TypeError()
 | 
						|
    return (self >= other) and (self != other)
 | 
						|
 | 
						|
 | 
						|
def nsset_update(self, *others):
 | 
						|
    for other in others:
 | 
						|
        if isinstance(other, collections.abc.Set):
 | 
						|
            self.unionSet_(other)
 | 
						|
        else:
 | 
						|
            self.unionSet_(set(other))
 | 
						|
 | 
						|
 | 
						|
def nsset_intersection_update(self, *others):
 | 
						|
    for other in others:
 | 
						|
        if isinstance(other, collections.abc.Set):
 | 
						|
            self.intersectSet_(other)
 | 
						|
        else:
 | 
						|
            self.intersectSet_(set(other))
 | 
						|
 | 
						|
 | 
						|
def nsset_difference_update(self, *others):
 | 
						|
    for other in others:
 | 
						|
        if isinstance(other, collections.abc.Set):
 | 
						|
            self.minusSet_(other)
 | 
						|
        else:
 | 
						|
            self.minusSet_(set(other))
 | 
						|
 | 
						|
 | 
						|
def nsset_symmetric_difference_update(self, other):
 | 
						|
    toadd = set()
 | 
						|
    toremove = set()
 | 
						|
 | 
						|
    if isinstance(other, collections.abc.Set):
 | 
						|
        totest = other
 | 
						|
    else:
 | 
						|
        totest = set(other)
 | 
						|
 | 
						|
    for value in self:
 | 
						|
        if value in totest:
 | 
						|
            toremove.add(value)
 | 
						|
    for value in totest:
 | 
						|
        if value not in self:
 | 
						|
            toadd.add(value)
 | 
						|
 | 
						|
    self.minusSet_(toremove)
 | 
						|
    self.unionSet_(toadd)
 | 
						|
 | 
						|
 | 
						|
def nsset_pop(self):
 | 
						|
    if len(self) == 0:
 | 
						|
        raise KeyError()
 | 
						|
 | 
						|
    v = self.anyObject()
 | 
						|
    self.removeObject_(v)
 | 
						|
    return container_unwrap(v, KeyError)
 | 
						|
 | 
						|
 | 
						|
def nsset_remove(self, value):
 | 
						|
    hash(value)
 | 
						|
    value = container_wrap(value)
 | 
						|
    if value not in self:
 | 
						|
        raise KeyError(value)
 | 
						|
    self.removeObject_(value)
 | 
						|
 | 
						|
 | 
						|
def nsset_discard(self, value):
 | 
						|
    hash(value)
 | 
						|
    self.removeObject_(container_wrap(value))
 | 
						|
 | 
						|
 | 
						|
def nsset_add(self, value):
 | 
						|
    hash(value)
 | 
						|
    self.addObject_(container_wrap(value))
 | 
						|
 | 
						|
 | 
						|
class nsset__iter__:
 | 
						|
    def __init__(self, value):
 | 
						|
        self._size = len(value)
 | 
						|
        self._enum = value.objectEnumerator()
 | 
						|
 | 
						|
    def __length_hint__(self):
 | 
						|
        return self._size
 | 
						|
 | 
						|
    def __iter__(self):
 | 
						|
        return self
 | 
						|
 | 
						|
    def __next__(self):
 | 
						|
        self._size -= 1
 | 
						|
        return container_unwrap(self._enum.nextObject(), StopIteration)
 | 
						|
 | 
						|
 | 
						|
addConvenienceForClass(
 | 
						|
    "NSSet",
 | 
						|
    (
 | 
						|
        ("__len__", lambda self: self.count()),
 | 
						|
        ("__iter__", lambda self: nsset__iter__(self)),
 | 
						|
        ("__contains__", nsset__contains__),
 | 
						|
        ("isdisjoint", nsset_isdisjoint),
 | 
						|
        ("union", nsset_union),
 | 
						|
        ("intersection", nsset_intersection),
 | 
						|
        ("difference", nsset_difference),
 | 
						|
        ("symmetric_difference", nsset_symmetric_difference),
 | 
						|
        ("issubset", nsset_issubset),
 | 
						|
        ("__eq__", nsset__eq__),
 | 
						|
        ("__ne__", nsset__ne__),
 | 
						|
        ("__le__", nsset__le__),
 | 
						|
        ("__lt__", nsset__lt__),
 | 
						|
        ("issuperset", nsset_issuperset),
 | 
						|
        ("__ge__", nsset__ge__),
 | 
						|
        ("__gt__", nsset__gt__),
 | 
						|
        ("__or__", nsset__or__),
 | 
						|
        ("__ror__", nsset__ror__),
 | 
						|
        ("__and__", nsset__and__),
 | 
						|
        ("__rand__", nsset__rand__),
 | 
						|
        ("__xor__", nsset__xor__),
 | 
						|
        ("__rxor__", nsset__xor__),
 | 
						|
        ("__sub__", nsset__sub__),
 | 
						|
        ("__rsub__", nsset__rsub__),
 | 
						|
    ),
 | 
						|
)
 | 
						|
 | 
						|
addConvenienceForClass(
 | 
						|
    "NSMutableSet",
 | 
						|
    (
 | 
						|
        ("add", nsset_add),
 | 
						|
        ("remove", nsset_remove),
 | 
						|
        ("discard", nsset_discard),
 | 
						|
        ("update", nsset_update),
 | 
						|
        ("intersection_update", nsset_intersection_update),
 | 
						|
        ("difference_update", nsset_difference_update),
 | 
						|
        ("symmetric_difference_update", nsset_symmetric_difference_update),
 | 
						|
        ("clear", lambda self: self.removeAllObjects()),
 | 
						|
        ("pop", nsset_pop),
 | 
						|
    ),
 | 
						|
)
 | 
						|
 | 
						|
 | 
						|
def nsset_new(cls, sequence=None):
 | 
						|
    if not sequence:
 | 
						|
        return NSSet.set()
 | 
						|
 | 
						|
    if isinstance(sequence, (NSSet, set, frozenset)):
 | 
						|
        return NSSet.set().setByAddingObjectsFromSet_(sequence)
 | 
						|
 | 
						|
    else:
 | 
						|
        return NSSet.set().setByAddingObjectsFromSet_(set(sequence))
 | 
						|
 | 
						|
 | 
						|
def nsmutableset_new(cls, sequence=None):
 | 
						|
    if not sequence:
 | 
						|
        value = NSMutableSet.set()
 | 
						|
 | 
						|
    elif isinstance(sequence, (NSSet, set, frozenset)):
 | 
						|
        value = NSMutableSet.set()
 | 
						|
        value.unionSet_(sequence)
 | 
						|
 | 
						|
    else:
 | 
						|
        value = NSMutableSet.set()
 | 
						|
        value.unionSet_(set(sequence))
 | 
						|
 | 
						|
    return value
 | 
						|
 | 
						|
 | 
						|
addConvenienceForClass("NSSet", (("__new__", staticmethod(nsset_new)),))
 | 
						|
 | 
						|
addConvenienceForClass("NSMutableSet", (("__new__", staticmethod(nsmutableset_new)),))
 |