docs: def get_filename_ds(ds, dump=True, paths=None, **kwargs):
      """
      Return the filename of the corresponding to a dataset
  
      This method returns the path to the `ds` or saves the dataset
      if there exists no filename
  
      Parameters
      ----------
      ds: xarray.Dataset
          The dataset you want the path information for
      dump: bool
          If True and the dataset has not been dumped so far, it is dumped to a
          temporary file or the one generated by `paths` is used
      paths: iterable or True
          An iterator over filenames to use if a dataset has no filename.
          If paths is ``True``, an iterator over temporary files will be
          created without raising a warning
  
      Other Parameters
      ----------------
      ``**kwargs``
          Any other keyword for the :func:`to_netcdf` function
      %(xarray.Dataset.to_netcdf.parameters)s
  
      Returns
      -------
      str or None
          None, if the dataset has not yet been dumped to the harddisk and
          `dump` is False, otherwise the complete the path to the input
          file
      str
          The module of the :class:`xarray.backends.common.AbstractDataStore`
          instance that is used to hold the data
      str
          The class name of the
          :class:`xarray.backends.common.AbstractDataStore` instance that is
          used to open the data
      """
      from tempfile import NamedTemporaryFile
  
      # if already specified, return that filename
      if ds.psy._filename is not None:
          return tuple([ds.psy._filename] + list(ds.psy.data_store))
  
      def dump_nc():
          # make sure that the data store is not closed by providing a
          # write argument
          if xr_version < (0, 11):
              kwargs.setdefault('writer', xarray_api.ArrayWriter())
              store = to_netcdf(ds, fname, **kwargs)
          else:
              # `writer` parameter was removed by
              # https://github.com/pydata/xarray/pull/2261
              kwargs.setdefault('multifile', True)
              store = to_netcdf(ds, fname, **kwargs)[1]
          store_mod = store.__module__
          store_cls = store.__class__.__name__
          ds._file_obj = store
          return store_mod, store_cls
  
      def tmp_it():
          while True:
              yield NamedTemporaryFile(suffix='.nc').name
  
      fname = None
      if paths is True or (dump and paths is None):
          paths = tmp_it()
      elif paths is not None:
          if isstring(paths):
              paths = iter([paths])
          else:
              paths = iter(paths)
      # try to get the filename from  the data store of the obj
      store_mod, store_cls = ds.psy.data_store
      if store_mod is not None:
          store = ds._file_obj
          # try several engines
          if hasattr(store, 'file_objs'):
              fname = []
              store_mod = []
              store_cls = []
              for obj in store.file_objs:  # mfdataset
                  _fname = None
                  for func in get_fname_funcs:
                      if _fname is None:
                          _fname = func(obj)
                          if _fname is not None:
                              fname.append(_fname)
                              store_mod.append(obj.__module__)
                              store_cls.append(obj.__class__.__name__)
              fname = tuple(fname)
              store_mod = tuple(store_mod)
              store_cls = tuple(store_cls)
          else:
              for func in get_fname_funcs:
                  fname = func(store)
                  if fname is not None:
                      break
      # check if paths is provided and if yes, save the file
      if fname is None and paths is not None:
          fname = next(paths, None)
          if dump and fname is not None:
              store_mod, store_cls = dump_nc()
  
      ds.psy.filename = fname
      ds.psy.data_store = (store_mod, store_cls)
  
      return fname, store_mod, store_cls