parameters: (self, s, lvars, within_list)
docstring: Expand a single "token" as necessary, appending the
          expansion to the current result.
  
          This handles expanding different types of things (strings,
          lists, callables) appropriately.  It calls the wrapper
          substitute() method to re-expand things as necessary, so that
          the results of expansions of side-by-side strings still get
          re-evaluated separately, not smushed together.
docstring_summary: Expand a single "token" as necessary, appending the
          expansion to the current result.
docstring_tokens: Expand a single token as necessary appending the expansion to the current result .
function: def expand(self, s, lvars, within_list):
          """Expand a single "token" as necessary, appending the
          expansion to the current result.
  
          This handles expanding different types of things (strings,
          lists, callables) appropriately.  It calls the wrapper
          substitute() method to re-expand things as necessary, so that
          the results of expansions of side-by-side strings still get
          re-evaluated separately, not smushed together.
          """
  
          if is_String(s):
              try:
                  s0, s1 = s[:2]
              except (IndexError, ValueError):
                  self.append(s)
                  return
              if s0 != '$':
                  self.append(s)
                  return
              if s1 == '$':
                  self.append('$')
              elif s1 == '(':
                  self.open_strip('$(')
              elif s1 == ')':
                  self.close_strip('$)')
              else:
                  key = s[1:]
                  if key[0] == '{' or key.find('.') >= 0:
                      if key[0] == '{':
                          key = key[1:-1]
  
                  # Store for error messages if we fail to expand the
                  # value
                  old_s = s
                  s = None
                  if key in lvars:
                       s = lvars[key]
                  elif key in self.gvars:
                       s = self.gvars[key]
                  else:
                       try:
                           s = eval(key, self.gvars, lvars)
                       except KeyboardInterrupt:
                           raise
                       except Exception as e:
                           if e.__class__ in AllowableExceptions:
                               return
                           raise_exception(e, lvars['TARGETS'], old_s)
  
                  if s is None and NameError not in AllowableExceptions:
                       raise_exception(NameError(), lvars['TARGETS'], old_s)
                  elif s is None:
                       return
  
                  # If the string is already full expanded there's no
                  # need to continue recursion.
                  if self.expanded(s):
                      self.append(s)
                      return
  
                  # Before re-expanding the result, handle
                  # recursive expansion by copying the local
                  # variable dictionary and overwriting a null
                  # string for the value of the variable name
                  # we just expanded.
                  lv = lvars.copy()
                  var = key.split('.')[0]
                  lv[var] = ''
                  self.substitute(s, lv, 0)
                  self.this_word()
          elif is_Sequence(s):
              for a in s:
                  self.substitute(a, lvars, 1)
                  self.next_word()
          elif callable(s):
              try:
                  s = s(target=lvars['TARGETS'],
                       source=lvars['SOURCES'],
                       env=self.env,
                       for_signature=(self.mode != SUBST_CMD))
              except TypeError:
                  # This probably indicates that it's a callable
                  # object that doesn't match our calling arguments
                  # (like an Action).
                  if self.mode == SUBST_RAW:
                      self.append(s)
                      return
                  s = self.conv(s)
              self.substitute(s, lvars, within_list)
          elif s is None:
              self.this_word()
          else:
              self.append(s)
function_tokens: def expand ( self , s , lvars , within_list ) : if is_String ( s ) : try : s0 , s1 = s [ : 2 ] except ( IndexError , ValueError ) : self . append ( s ) return if s0 != '$' : self . append ( s ) return if s1 == '$' : self . append ( '$' ) elif s1 == '(' : self . open_strip ( '$(' ) elif s1 == ')' : self . close_strip ( '$)' ) else : key = s [ 1 : ] if key [ 0 ] == '{' or key . find ( '.' ) >= 0 : if key [ 0 ] == '{' : key = key [ 1 : - 1 ] # Store for error messages if we fail to expand the # value old_s = s s = None if key in lvars : s = lvars [ key ] elif key in self . gvars : s = self . gvars [ key ] else : try : s = eval ( key , self . gvars , lvars ) except KeyboardInterrupt : raise except Exception as e : if e . __class__ in AllowableExceptions : return raise_exception ( e , lvars [ 'TARGETS' ] , old_s ) if s is None and NameError not in AllowableExceptions : raise_exception ( NameError ( ) , lvars [ 'TARGETS' ] , old_s ) elif s is None : return # If the string is already full expanded there's no # need to continue recursion. if self . expanded ( s ) : self . append ( s ) return # Before re-expanding the result, handle # recursive expansion by copying the local # variable dictionary and overwriting a null # string for the value of the variable name # we just expanded. lv = lvars . copy ( ) var = key . split ( '.' ) [ 0 ] lv [ var ] = '' self . substitute ( s , lv , 0 ) self . this_word ( ) elif is_Sequence ( s ) : for a in s : self . substitute ( a , lvars , 1 ) self . next_word ( ) elif callable ( s ) : try : s = s ( target = lvars [ 'TARGETS' ] , source = lvars [ 'SOURCES' ] , env = self . env , for_signature = ( self . mode != SUBST_CMD ) ) except TypeError : # This probably indicates that it's a callable # object that doesn't match our calling arguments # (like an Action). if self . mode == SUBST_RAW : self . append ( s ) return s = self . conv ( s ) self . substitute ( s , lvars , within_list ) elif s is None : self . this_word ( ) else : self . append ( s )