code: def _parse_path(path_args):
          
          if len(path_args) == 0:
              raise ValueError("Key path must not be empty.")
  
          kind_list = path_args[::2]
          id_or_name_list = path_args[1::2]
          # Dummy sentinel value to pad incomplete key to even length path.
          partial_ending = object()
          if len(path_args) % 2 == 1:
              id_or_name_list += (partial_ending,)
  
          result = []
          for kind, id_or_name in zip(kind_list, id_or_name_list):
              curr_key_part = {}
              if isinstance(kind, six.string_types):
                  curr_key_part["kind"] = kind
              else:
                  raise ValueError(kind, "Kind was not a string.")
  
              if isinstance(id_or_name, six.string_types):
                  curr_key_part["name"] = id_or_name
              elif isinstance(id_or_name, six.integer_types):
                  curr_key_part["id"] = id_or_name
              elif id_or_name is not partial_ending:
                  raise ValueError(id_or_name, "ID/name was not a string or integer.")
  
              result.append(curr_key_part)
  
          return result
docs: Parses positional arguments into key path with kinds and IDs.
  
          :type path_args: tuple
          :param path_args: A tuple from positional arguments. Should be
                            alternating list of kinds (string) and ID/name
                            parts (int or string).
  
          :rtype: :class:`list` of :class:`dict`
          :returns: A list of key parts with kind and ID or name set.
          :raises: :class:`ValueError` if there are no ``path_args``, if one of
                   the kinds is not a string or if one of the IDs/names is not
                   a string or an integer.