docs: def _split_keys(mapping, separator='.', colliding=None):
      """
      Recursively walks *mapping* to split keys that contain the separator into
      nested mappings.
  
      .. note::
  
          Keys not of type `str` are not supported and will raise errors.
  
      :param mapping: the mapping to process
      :param separator: the character (sequence) to use as the separator between
          keys
      :return: a mapping where keys containing *separator* are split into nested
          mappings
      """
      result = {}
  
      for key, value in mapping.items():
          if isinstance(value, Mapping):
              # recursively split key(s) in value
              value = _split_keys(value, separator)
  
          # reject non-str keys, avoid complicating access patterns
          if not isinstance(key, str):
              raise ValueError('non-str type keys ({0}, {0.__class__.__module__}.{0.__class__.__name__}) '
                               'not supported'.format(key))
  
          if separator in key:
              # update key to be the first part before the separator
              key, rest = key.split(separator, 1)
              # use rest as the new key of value, recursively split that and update value
              value = _split_keys({rest: value}, separator)
  
          if colliding and key in colliding:
              # warn about configured keys colliding with Configuration members
              warnings.warn('key {key} collides with a named member, use get() method to retrieve the '
                            'value for {key}'.format(key=key),
                            UserWarning)
  
          # merge the result so far with the (possibly updated / fixed / split) current key and value
          _merge(result, {key: value})
  
      return result