1  import re 
  2  import weakref 
  3  from buildbot import util 
  4   
  6      """ 
  7      I represent a set of properties that can be interpolated into various 
  8      strings in buildsteps. 
  9   
 10      @ivar properties: dictionary mapping property values to tuples  
 11          (value, source), where source is a string identifing the source 
 12          of the property. 
 13   
 14      Objects of this class can be read like a dictionary -- in this case, 
 15      only the property value is returned. 
 16   
 17      As a special case, a property value of None is returned as an empty  
 18      string when used as a mapping. 
 19      """ 
 20   
 21      compare_attrs = ('properties',) 
 22   
 24          """ 
 25          @param kwargs: initial property values (for testing) 
 26          """ 
 27          self.properties = {} 
 28          self.pmap = PropertyMap(self) 
 29          if kwargs: self.update(kwargs, "TEST") 
  30   
 32          d = self.__dict__.copy() 
 33          del d['pmap'] 
 34          return d 
  35   
 39   
 42   
 44          """Just get the value for this property.""" 
 45          rv = self.properties[name][0] 
 46          return rv 
  47   
 50   
 52          """Get the value for the given property.""" 
 53          return self.properties.get(name, (default,))[0] 
  54   
 57   
 59          """Return the properties as a sorted list of (name, value, source)""" 
 60          l = [ (k, v[0], v[1]) for k,v in self.properties.items() ] 
 61          l.sort() 
 62          return l 
  63   
 65          return repr(dict([ (k,v[0]) for k,v in self.properties.iteritems() ])) 
  66   
 69   
 70 -    def update(self, dict, source): 
  71          """Update this object from a dictionary, with an explicit source specified.""" 
 72          for k, v in dict.items(): 
 73              self.properties[k] = (v, source) 
  74   
 78   
 80          """ 
 81          Return a variant of value that has any WithProperties objects 
 82          substituted.  This recurses into Python's compound data types. 
 83          """ 
 84           
 85           
 86          if isinstance(value, (str, unicode)): 
 87              return value 
 88          elif isinstance(value, WithProperties): 
 89              return value.render(self.pmap) 
 90          elif isinstance(value, list): 
 91              return [ self.render(e) for e in value ] 
 92          elif isinstance(value, tuple): 
 93              return tuple([ self.render(e) for e in value ]) 
 94          elif isinstance(value, dict): 
 95              return dict([ (self.render(k), self.render(v)) for k,v in value.iteritems() ]) 
 96          else: 
 97              return value 
   98   
100      """ 
101      Privately-used mapping object to implement WithProperties' substitutions, 
102      including the rendering of None as ''. 
103      """ 
104      colon_minus_re = re.compile(r"(.*):-(.*)") 
105      colon_plus_re = re.compile(r"(.*):\+(.*)") 
109   
 139   
141      """ 
142      This is a marker class, used fairly widely to indicate that we 
143      want to interpolate build properties. 
144      """ 
145   
146      compare_attrs = ('fmtstring', 'args') 
147   
149          self.fmtstring = fmtstring 
150          self.args = args 
 151   
153          if self.args: 
154              strings = [] 
155              for name in self.args: 
156                  strings.append(pmap[name]) 
157              s = self.fmtstring % tuple(strings) 
158          else: 
159              s = self.fmtstring % pmap 
160          return s 
  161