code: def __viable_source_types_real (target_type):
      
      assert isinstance(target_type, basestring)
      generators = []
  
      # 't0' is the initial list of target types we need to process to get a list
      # of their viable source target types. New target types will not be added to
      # this list.
      t0 = type.all_bases (target_type)
  
  
      # 't' is the list of target types which have not yet been processed to get a
      # list of their viable source target types. This list will get expanded as
      # we locate more target types to process.
      t = t0
  
      result = []
      while t:
          # Find all generators for current type.
          # Unlike 'find_viable_generators' we don't care about prop_set.
          generators = __type_to_generators.get (t [0], [])
          t = t[1:]
  
          for g in generators:
              if not g.source_types():
                  # Empty source types -- everything can be accepted
                  result = "*"
                  # This will terminate outer loop.
                  t = None
                  break
  
              for source_type in g.source_types ():
                  if not source_type in result:
                      # If generator accepts 'source_type' it
                      # will happily accept any type derived from it
                      all = type.all_derived (source_type)
                      for n in all:
                          if not n in result:
  
                              # Here there is no point in adding target types to
                              # the list of types to process in case they are or
                              # have already been on that list. We optimize this
                              # check by realizing that we only need to avoid the
                              # original target type's base types. Other target
                              # types that are or have been on the list of target
                              # types to process have been added to the 'result'
                              # list as well and have thus already been eliminated
                              # by the previous if.
                              if not n in t0:
                                  t.append (n)
                              result.append (n)
  
      return result
docs: Returns a list of source type which can possibly be converted
          to 'target_type' by some chain of generator invocation.
  
          More formally, takes all generators for 'target_type' and
          returns union of source types for those generators and result
          of calling itself recusrively on source types.