code: def _subs_tree(cls, tvars=None, args=None):
      
  
      if cls.__origin__ is None:
          return cls
      # Make of chain of origins (i.e. cls -> cls.__origin__)
      current = cls.__origin__
      orig_chain = []
      while current.__origin__ is not None:
          orig_chain.append(current)
          current = current.__origin__
      # Replace type variables in __args__ if asked ...
      tree_args = []
      for arg in cls.__args__:
          tree_args.append(_replace_arg(arg, tvars, args))
      # ... then continue replacing down the origin chain.
      for ocls in orig_chain:
          new_tree_args = []
          for arg in ocls.__args__:
              new_tree_args.append(_replace_arg(arg, ocls.__parameters__, tree_args))
          tree_args = new_tree_args
      return tree_args
docs: An internal helper function: calculate substitution tree
      for generic cls after replacing its type parameters with
      substitutions in tvars -> args (if any).
      Repeat the same following __origin__'s.
  
      Return a list of arguments with all possible substitutions
      performed. Arguments that are generic classes themselves are represented
      as tuples (so that no new classes are created by this function).
      For example: _subs_tree(List[Tuple[int, T]][str]) == [(Tuple, int, str)]