Package dns :: Module set
[hide private]
[frames] | no frames]

Source Code for Module dns.set

  1  # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 
  2  # 
  3  # Permission to use, copy, modify, and distribute this software and its 
  4  # documentation for any purpose with or without fee is hereby granted, 
  5  # provided that the above copyright notice and this permission notice 
  6  # appear in all copies. 
  7  # 
  8  # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 
  9  # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 
 10  # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 
 11  # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
 12  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
 13  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 
 14  # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
 15   
 16  """A simple Set class.""" 
 17   
18 -class Set(object):
19 """A simple set class. 20 21 This class implements a mutable set using a list as the container. 22 We don't use Python's set class because it's not indexable. 23 24 @ivar items: A list of the items which are in the set 25 @type items: list""" 26 27 __slots__ = ['items'] 28
29 - def __init__(self, items=None):
30 """Initialize the set. 31 32 @param items: the initial set of items 33 @type items: any iterable or None 34 """ 35 36 self.items = [] 37 if not items is None: 38 for item in items: 39 self.add(item)
40
41 - def __repr__(self):
42 return "dns.simpleset.Set(%s)" % repr(self.items)
43
44 - def add(self, item):
45 """Add an item to the set.""" 46 if not item in self.items: 47 self.items.append(item)
48
49 - def remove(self, item):
50 """Remove an item from the set.""" 51 self.items.remove(item)
52
53 - def discard(self, item):
54 """Remove an item from the set if present.""" 55 try: 56 self.items.remove(item) 57 except ValueError: 58 pass
59
60 - def _clone(self):
61 """Make a (shallow) copy of the set. 62 63 There is a 'clone protocol' that subclasses of this class 64 should use. To make a copy, first call your super's _clone() 65 method, and use the object returned as the new instance. Then 66 make shallow copies of the attributes defined in the subclass. 67 68 This protocol allows us to write the set algorithms that 69 return new instances (e.g. union) once, and keep using them in 70 subclasses. 71 """ 72 73 cls = self.__class__ 74 obj = cls.__new__(cls) 75 obj.items = list(self.items) 76 return obj
77
78 - def __copy__(self):
79 """Make a (shallow) copy of the set.""" 80 return self._clone()
81
82 - def copy(self):
83 """Make a (shallow) copy of the set.""" 84 return self._clone()
85
86 - def union_update(self, other):
87 """Update the set, adding any elements from other which are not 88 already in the set. 89 @param other: the collection of items with which to update the set 90 @type other: Set object 91 """ 92 if not isinstance(other, Set): 93 raise ValueError('other must be a Set instance') 94 if self is other: 95 return 96 for item in other.items: 97 self.add(item)
98
99 - def intersection_update(self, other):
100 """Update the set, removing any elements from other which are not 101 in both sets. 102 @param other: the collection of items with which to update the set 103 @type other: Set object 104 """ 105 if not isinstance(other, Set): 106 raise ValueError('other must be a Set instance') 107 if self is other: 108 return 109 # we make a copy of the list so that we can remove items from 110 # the list without breaking the iterator. 111 for item in list(self.items): 112 if item not in other.items: 113 self.items.remove(item)
114
115 - def difference_update(self, other):
116 """Update the set, removing any elements from other which are in 117 the set. 118 @param other: the collection of items with which to update the set 119 @type other: Set object 120 """ 121 if not isinstance(other, Set): 122 raise ValueError('other must be a Set instance') 123 if self is other: 124 self.items = [] 125 else: 126 for item in other.items: 127 self.discard(item)
128
129 - def union(self, other):
130 """Return a new set which is the union of I{self} and I{other}. 131 132 @param other: the other set 133 @type other: Set object 134 @rtype: the same type as I{self} 135 """ 136 137 obj = self._clone() 138 obj.union_update(other) 139 return obj
140
141 - def intersection(self, other):
142 """Return a new set which is the intersection of I{self} and I{other}. 143 144 @param other: the other set 145 @type other: Set object 146 @rtype: the same type as I{self} 147 """ 148 149 obj = self._clone() 150 obj.intersection_update(other) 151 return obj
152
153 - def difference(self, other):
154 """Return a new set which I{self} - I{other}, i.e. the items 155 in I{self} which are not also in I{other}. 156 157 @param other: the other set 158 @type other: Set object 159 @rtype: the same type as I{self} 160 """ 161 162 obj = self._clone() 163 obj.difference_update(other) 164 return obj
165
166 - def __or__(self, other):
167 return self.union(other)
168
169 - def __and__(self, other):
170 return self.intersection(other)
171
172 - def __add__(self, other):
173 return self.union(other)
174
175 - def __sub__(self, other):
176 return self.difference(other)
177
178 - def __ior__(self, other):
179 self.union_update(other) 180 return self
181
182 - def __iand__(self, other):
183 self.intersection_update(other) 184 return self
185
186 - def __iadd__(self, other):
187 self.union_update(other) 188 return self
189
190 - def __isub__(self, other):
191 self.difference_update(other) 192 return self
193
194 - def update(self, other):
195 """Update the set, adding any elements from other which are not 196 already in the set. 197 @param other: the collection of items with which to update the set 198 @type other: any iterable type""" 199 for item in other: 200 self.add(item)
201
202 - def clear(self):
203 """Make the set empty.""" 204 self.items = []
205
206 - def __eq__(self, other):
207 # Yes, this is inefficient but the sets we're dealing with are 208 # usually quite small, so it shouldn't hurt too much. 209 for item in self.items: 210 if not item in other.items: 211 return False 212 for item in other.items: 213 if not item in self.items: 214 return False 215 return True
216
217 - def __ne__(self, other):
218 return not self.__eq__(other)
219
220 - def __len__(self):
221 return len(self.items)
222
223 - def __iter__(self):
224 return iter(self.items)
225
226 - def __getitem__(self, i):
227 return self.items[i]
228
229 - def __delitem__(self, i):
230 del self.items[i]
231
232 - def __getslice__(self, i, j):
233 return self.items[i:j]
234
235 - def __delslice__(self, i, j):
236 del self.items[i:j]
237
238 - def issubset(self, other):
239 """Is I{self} a subset of I{other}? 240 241 @rtype: bool 242 """ 243 244 if not isinstance(other, Set): 245 raise ValueError('other must be a Set instance') 246 for item in self.items: 247 if not item in other.items: 248 return False 249 return True
250
251 - def issuperset(self, other):
252 """Is I{self} a superset of I{other}? 253 254 @rtype: bool 255 """ 256 257 if not isinstance(other, Set): 258 raise ValueError('other must be a Set instance') 259 for item in other.items: 260 if not item in self.items: 261 return False 262 return True
263