1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
"""sets module
This module provides some Set classes for dealing with MySQL data.
"""
class Set:
"""A simple class for handling sets. Sets are immutable in the same
way numbers are."""
def __init__(self, *values):
"""Use values to initialize the Set."""
self._values = values
def __contains__(self, value):
return value in self._values and 1 or 0
def __str__(self):
"""Returns the values as a comma-separated string."""
from string import join
return join(map(str, self._values),',')
def __repr__(self):
return "%s%s" % (self.__class__.__name__, `self._values`)
def __or__(self, other):
"""Union."""
values = list(self._values)
if isinstance(other, Set):
for v in other._values:
if v not in values:
values.append(v)
elif other not in self._values:
values.append(other)
return apply(self.__class__, values)
__add__ = __or__
def __sub__(self, other):
values = list(self._values)
if isinstance(other, Set):
for v in other._values:
if v in values:
values.remove(v)
elif other in self:
values.remove(other)
return apply(self.__class__, tuple(values))
def __and__(self, other):
"Intersection."
values = []
if isinstance(other, Set):
for v in self._values:
if v in other:
values.append(v)
elif other in self:
values.append(other)
return apply(self.__class__, tuple(values))
__mul__ = __and__
def __xor__(self, other):
"Intersection's complement."
return (self|other)-(self&other)
def __getitem__(self, n):
return self._values[n]
def __getslice__(self, n1, n2):
return self._values[n1:n2]
def __len__(self):
return len(self._values)
def __hash__(self):
return hash(self._values)
def __cmp__(self, other):
if isinstance(other, Set):
if not self ^ other:
return 0
elif self & other == self:
return 1
else:
return -1
elif other in self._values:
return 0
elif other > self._values:
return 1
else:
return -1
# rich comparison operators for Python 2.1 and up
def __ne__(self, other):
return self ^ other
def __eq__(self, other):
if not self != other:
return self
else:
return self.__class__()
def __le__(self, other):
return self & other == self
def __lt__(self, other):
if self <= other and self ^ other:
return self
else:
return self.__class__()
def __ge__(self, other):
return self & other == other
def __gt__(self, other):
if self >= other and self ^ other:
return self
else:
return self.__class__()
class DBAPISet(Set):
"""A special type of set for which A == x is true if A is a
DBAPISet and x is a member of that set."""
# Note that Set.__cmp__ works perfectly well in this case, if
# we are using < Python 2.1. It's just broken for <, >, etc.
def __ne__(self, other):
if isinstance(other, Set): # yes, Set
return self % other
elif other in self._values:
return 0
else:
return 1
def __eq__(self, other):
if self != other:
return self.__class__()
else:
return self
|