docs: def iter_all(self, recursive=False, path=None, key='path'):
          """
          Args:
              recursive: if ``True``, recurse into sub-sections
  
              path (tuple or string): optional path to limit iteration over.
  
              key: ``path`` (default), ``str_path``, ``name``, ``None``, or a function to calculate the key from
                  ``(k, v)`` tuple.
  
          Returns:
              iterator: iterator over ``(path, obj)`` pairs of all items and
              sections contained in this section.
          """
          if isinstance(key, six.string_types) or key is None:
              if key in _iter_emitters:
                  emitter = _iter_emitters[key]
              else:
                  raise ValueError('Invalid key {!r}'.format(key))
          else:
              emitter = lambda k, v, _, f=key: (f(k, v), v)
  
          for p, obj in self._get_path_iterator(recursive=recursive, path=path):
              yield emitter(p, obj, self.settings.str_path_separator)