Package SCons :: Package compat :: Module _scons_sets15
[hide private]
[frames] | no frames]

Source Code for Module SCons.compat._scons_sets15

  1  # 
  2  # A Set class that works all the way back to Python 1.5.  From: 
  3  # 
  4  #       Python Cookbook:  Yet another Set class for Python 
  5  #       http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/106469 
  6  #       Goncalo Rodriques 
  7  # 
  8  #       This is a pure Pythonic implementation of a set class.  The syntax 
  9  #       and methods implemented are, for the most part, borrowed from 
 10  #       PEP 218 by Greg Wilson. 
 11  # 
 12  # Note that this class violates the formal definition of a set() by adding 
 13  # a __getitem__() method so we can iterate over a set's elements under 
 14  # Python 1.5 and 2.1, which don't support __iter__() and iterator types. 
 15  # 
 16   
 17  import string 
 18   
19 -class Set:
20 """The set class. It can contain mutable objects.""" 21
22 - def __init__(self, seq = None):
23 """The constructor. It can take any object giving an iterator as an optional 24 argument to populate the new set.""" 25 self.elems = [] 26 if seq: 27 for elem in seq: 28 if elem not in self.elems: 29 self.elems.append(elem)
30
31 - def __str__(self):
32 return "{%s}" % string.join(map(str, self.elems), ", ")
33 34
35 - def copy(self):
36 """Shallow copy of a set object.""" 37 return Set(self.elems)
38
39 - def __contains__(self, elem):
40 return elem in self.elems
41
42 - def __len__(self):
43 return len(self.elems)
44
45 - def __getitem__(self, index):
46 # Added so that Python 1.5 can iterate over the elements. 47 # The cookbook recipe's author didn't like this because there 48 # really isn't any order in a set object, but this is necessary 49 # to make the class work well enough for our purposes. 50 return self.elems[index]
51
52 - def items(self):
53 """Returns a list of the elements in the set.""" 54 return self.elems
55
56 - def add(self, elem):
57 """Add one element to the set.""" 58 if elem not in self.elems: 59 self.elems.append(elem)
60
61 - def remove(self, elem):
62 """Remove an element from the set. Return an error if elem is not in the set.""" 63 try: 64 self.elems.remove(elem) 65 except ValueError: 66 raise LookupError, "Object %s is not a member of the set." % str(elem)
67
68 - def discard(self, elem):
69 """Remove an element from the set. Do nothing if elem is not in the set.""" 70 try: 71 self.elems.remove(elem) 72 except ValueError: 73 pass
74
75 - def sort(self, func=cmp):
76 self.elems.sort(func)
77 78 #Define an iterator for a set.
79 - def __iter__(self):
80 return iter(self.elems)
81 82 #The basic binary operations with sets.
83 - def __or__(self, other):
84 """Union of two sets.""" 85 ret = self.copy() 86 for elem in other.elems: 87 if elem not in ret: 88 ret.elems.append(elem) 89 return ret
90
91 - def __sub__(self, other):
92 """Difference of two sets.""" 93 ret = self.copy() 94 for elem in other.elems: 95 ret.discard(elem) 96 return ret
97
98 - def __and__(self, other):
99 """Intersection of two sets.""" 100 ret = Set() 101 for elem in self.elems: 102 if elem in other.elems: 103 ret.elems.append(elem) 104 return ret
105
106 - def __add__(self, other):
107 """Symmetric difference of two sets.""" 108 ret = Set() 109 temp = other.copy() 110 for elem in self.elems: 111 if elem in temp.elems: 112 temp.elems.remove(elem) 113 else: 114 ret.elems.append(elem) 115 #Add remaining elements. 116 for elem in temp.elems: 117 ret.elems.append(elem) 118 return ret
119
120 - def __mul__(self, other):
121 """Cartesian product of two sets.""" 122 ret = Set() 123 for elemself in self.elems: 124 x = map(lambda other, s=elemself: (s, other), other.elems) 125 ret.elems.extend(x) 126 return ret
127 128 #Some of the binary comparisons.
129 - def __lt__(self, other):
130 """Returns 1 if the lhs set is contained but not equal to the rhs set.""" 131 if len(self.elems) < len(other.elems): 132 temp = other.copy() 133 for elem in self.elems: 134 if elem in temp.elems: 135 temp.remove(elem) 136 else: 137 return 0 138 return len(temp.elems) == 0 139 else: 140 return 0
141
142 - def __le__(self, other):
143 """Returns 1 if the lhs set is contained in the rhs set.""" 144 if len(self.elems) <= len(other.elems): 145 ret = 1 146 for elem in self.elems: 147 if elem not in other.elems: 148 ret = 0 149 break 150 return ret 151 else: 152 return 0
153
154 - def __eq__(self, other):
155 """Returns 1 if the sets are equal.""" 156 if len(self.elems) != len(other.elems): 157 return 0 158 else: 159 return len(self - other) == 0
160