docs: def process_path(pth):
      """ Processes paths.
  
      Processes the provided path and breaks it into it Group part
      (`groupname`) and target part (`targetname`). ``bytes`` paths are
      converted to ``str``. Separated paths are given as an iterable of
      ``str`` and ``bytes``. Each part of a separated path is escaped
      using ``escape_path``. Otherwise, the path is assumed to be already
      escaped. Escaping is done so that targets with a part that starts
      with one or more periods, contain slashes, and/or contain nulls can
      be used without causing the wrong Group to be looked in or the wrong
      target to be looked at. It essentially allows one to make a Dataset
      named ``'..'`` or ``'a/a'`` instead of moving around in the Dataset
      hierarchy.
  
      All paths are POSIX style.
  
      .. versionadded:: 0.2
  
      Parameters
      ----------
      pth : str or bytes or iterable of str or bytes
          The POSIX style path as a ``str`` or ``bytes`` or the
          separated path in an iterable with the elements being ``str``
          and ``bytes``. For separated paths, escaping will be done
          on each part.
  
      Returns
      -------
      groupname : str
          The path to the Group containing the target `pth` was pointing
          to.
      targetname : str
          The name of the target pointed to by `pth` in the Group
          `groupname`.
  
      Raises
      ------
      TypeError
          If `pth` is not of the right type.
  
      See Also
      --------
      escape_path
  
      """
      # Do conversions and possibly escapes.
      if isinstance(pth, bytes):
          p = pth.decode('utf-8')
      elif (sys.hexversion >= 0x03000000 and isinstance(pth, str)) \
              or (sys.hexversion < 0x03000000 \
              and isinstance(pth, unicode)):
          p = pth
      elif not isinstance(pth, collections.Iterable):
          raise TypeError('p must be str, bytes, or an iterable '
                          + 'solely of one of those two.')
      else:
          # Check that all elements are unicode or bytes.
          if sys.hexversion >= 0x03000000:
              if not all([isinstance(s, (bytes, str)) for s in pth]):
                  raise TypeError('Elements of p must be str or bytes.')
          else:
              if not all([isinstance(s, (str, unicode)) for s in pth]):
                  raise TypeError('Elements of p must be str or '
                                  + 'unicode.')
  
          # Escape (and possibly convert to unicode) each element and then
          # join them all together.
          parts = [None] * len(pth)
          for i, s in enumerate(pth):
              if isinstance(s, bytes):
                  s = s.decode('utf-8')
              parts[i] = escape_path(s)
          parts = tuple(parts)
          p = posixpath.join(*parts)
  
      # Remove double slashes and a non-root trailing slash.
      path = posixpath.normpath(p)
  
      # Extract the group name and the target name (will be a dataset if
      # data can be mapped to it, but will end up being made into a group
      # otherwise. As HDF5 files use posix path, conventions, posixpath
      # will do everything.
      groupname = posixpath.dirname(path)
      targetname = posixpath.basename(path)
  
      # If groupname got turned into blank, then it is just root.
      if len(groupname) == 0:
          groupname = b'/'.decode('ascii')
  
      # If targetname got turned blank, then it is the current directory.
      if len(targetname) == 0:
          targetname = b'.'.decode('ascii')
  
      return groupname, targetname