SCons.compat._scons_sets15

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