parameters: (target_type, prop_set)
return_statement: return viable_generators
docstring: Returns generators which can be used to construct target of specified type
          with specified properties. Uses the following algorithm:
          - iterates over requested target_type and all it's bases (in the order returned bt
            type.all-bases.
          - for each type find all generators that generate that type and which requirements
            are satisfied by properties.
          - if the set of generators is not empty, returns that set.
          
          Note: this algorithm explicitly ignores generators for base classes if there's
          at least one generator for requested target_type.
docstring_summary: Returns generators which can be used to construct target of specified type
          with specified properties. Uses the following algorithm:
          - iterates over requested target_type and all it's bases (in the order returned bt
            type.all-bases.
          - for each type find all generators that generate that type and which requirements
            are satisfied by properties.
          - if the set of generators is not empty, returns that set.
          
          Note: this algorithm explicitly ignores generators for base classes if there's
          at least one generator for requested target_type.
docstring_tokens: Returns generators which can be used to construct target of specified type with specified properties . Uses the following algorithm : - iterates over requested target_type and all it s bases ( in the order returned bt type . all - bases . - for each type find all generators that generate that type and which requirements are satisfied by properties . - if the set of generators is not empty returns that set . Note : this algorithm explicitly ignores generators for base classes if there s at least one generator for requested target_type .
function: def find_viable_generators_aux (target_type, prop_set):
      """ Returns generators which can be used to construct target of specified type
          with specified properties. Uses the following algorithm:
          - iterates over requested target_type and all it's bases (in the order returned bt
            type.all-bases.
          - for each type find all generators that generate that type and which requirements
            are satisfied by properties.
          - if the set of generators is not empty, returns that set.
          
          Note: this algorithm explicitly ignores generators for base classes if there's
          at least one generator for requested target_type.
      """
      # Select generators that can create the required target type.
      viable_generators = []
      initial_generators = []
  
      import type
  
      # Try all-type generators first. Assume they have
      # quite specific requirements.
      all_bases = type.all_bases(target_type)
          
      for t in all_bases:
          
          initial_generators = __type_to_generators.get(t, [])
          
          if initial_generators:
              dout("there are generators for this type")
              if t != target_type:
                  # We're here, when no generators for target-type are found,
                  # but there are some generators for a base type.
                  # We'll try to use them, but they will produce targets of
                  # base type, not of 'target-type'. So, we clone the generators
                  # and modify the list of target types.
                  generators2 = []
                  for g in initial_generators[:]:
                      # generators.register adds generator to the list of generators
                      # for toolsets, which is a bit strange, but should work.
                      # That list is only used when inheriting toolset, which
                      # should have being done before generators are run.
                      ng = g.clone_and_change_target_type(t, target_type)
                      generators2.append(ng)
                      register(ng)
                      
                  initial_generators = generators2
              break
      
      for g in initial_generators:
          dout("trying generator " + g.id()
               + "(" + str(g.source_types()) + "->" + str(g.target_types()) + ")")
          
          m = g.match_rank(prop_set)
          if m:
              dout("  is viable")
              viable_generators.append(g)            
                              
      return viable_generators
function_tokens: def find_viable_generators_aux ( target_type , prop_set ) : # Select generators that can create the required target type. viable_generators = [ ] initial_generators = [ ] import type # Try all-type generators first. Assume they have # quite specific requirements. all_bases = type . all_bases ( target_type ) for t in all_bases : initial_generators = __type_to_generators . get ( t , [ ] ) if initial_generators : dout ( "there are generators for this type" ) if t != target_type : # We're here, when no generators for target-type are found, # but there are some generators for a base type. # We'll try to use them, but they will produce targets of # base type, not of 'target-type'. So, we clone the generators # and modify the list of target types. generators2 = [ ] for g in initial_generators [ : ] : # generators.register adds generator to the list of generators # for toolsets, which is a bit strange, but should work. # That list is only used when inheriting toolset, which # should have being done before generators are run. ng = g . clone_and_change_target_type ( t , target_type ) generators2 . append ( ng ) register ( ng ) initial_generators = generators2 break for g in initial_generators : dout ( "trying generator " + g . id ( ) + "(" + str ( g . source_types ( ) ) + "->" + str ( g . target_types ( ) ) + ")" ) m = g . match_rank ( prop_set ) if m : dout ( "  is viable" ) viable_generators . append ( g ) return viable_generators