code: def concatechain(*generators: types.FrameGenerator, separator: str = ''):
      
      while True:
          try:
              next_ = [next(gen) for gen in generators]
              yield separator.join(next_)
          except StopIteration as exc:
              return exc.value
docs: Return a generator that in each iteration takes one value from each of the
      supplied generators, joins them together with the specified separator and
      yields the result. Stops as soon as any iterator raises StopIteration and
      returns the value contained in it.
  
      Primarily created for chaining string generators, hence the name.
  
      Args:
          generators: Any number of generators that yield types that can be
          joined together with the separator string.
          separator: A separator to insert between each value yielded by
          the different generators.
      Returns:
          A generator that yields strings that are the concatenation of one value
          from each of the generators, joined together with the separator string.