docs: def open_mfdataset(paths, chunks=None, concat_dim=_CONCAT_DIM_DEFAULT,
                     compat='no_conflicts', preprocess=None, engine=None,
                     lock=None, data_vars='all', coords='different',
                     autoclose=None, parallel=False, **kwargs):
      """Open multiple files as a single dataset.
  
      Requires dask to be installed. See documentation for details on dask [1].
      Attributes from the first dataset file are used for the combined dataset.
  
      Parameters
      ----------
      paths : str or sequence
          Either a string glob in the form "path/to/my/files/*.nc" or an explicit
          list of files to open.  Paths can be given as strings or as pathlib
          Paths.
      chunks : int or dict, optional
          Dictionary with keys given by dimension names and values given by chunk
          sizes. In general, these should divide the dimensions of each dataset.
          If int, chunk each dimension by ``chunks``.
          By default, chunks will be chosen to load entire input files into
          memory at once. This has a major impact on performance: please see the
          full documentation for more details [2].
      concat_dim : None, str, DataArray or Index, optional
          Dimension to concatenate files along. This argument is passed on to
          :py:func:`xarray.auto_combine` along with the dataset objects. You only
          need to provide this argument if the dimension along which you want to
          concatenate is not a dimension in the original datasets, e.g., if you
          want to stack a collection of 2D arrays along a third dimension.
          By default, xarray attempts to infer this argument by examining
          component files. Set ``concat_dim=None`` explicitly to disable
          concatenation.
      compat : {'identical', 'equals', 'broadcast_equals', 'no_conflicts'}, optional
          String indicating how to compare variables of the same name for
          potential conflicts when merging:
           * 'broadcast_equals': all values must be equal when variables are
             broadcast against each other to ensure common dimensions.
           * 'equals': all values and dimensions must be the same.
           * 'identical': all values, dimensions and attributes must be the
             same.
           * 'no_conflicts': only values which are not null in both datasets
             must be equal. The returned dataset then contains the combination
             of all non-null values.
      preprocess : callable, optional
          If provided, call this function on each dataset prior to concatenation.
          You can find the file-name from which each dataset was loaded in
          ``ds.encoding['source']``.
      engine : {'netcdf4', 'scipy', 'pydap', 'h5netcdf', 'pynio', 'cfgrib'}, \
          optional
          Engine to use when reading files. If not provided, the default engine
          is chosen based on available dependencies, with a preference for
          'netcdf4'.
      lock : False or duck threading.Lock, optional
          Resource lock to use when reading data from disk. Only relevant when
          using dask or another form of parallelism. By default, appropriate
          locks are chosen to safely read and write files with the currently
          active dask scheduler.
      data_vars : {'minimal', 'different', 'all' or list of str}, optional
          These data variables will be concatenated together:
  
           * 'minimal': Only data variables in which the dimension already
             appears are included.
           * 'different': Data variables which are not equal (ignoring
             attributes) across all datasets are also concatenated (as well as
             all for which dimension already appears). Beware: this option may
             load the data payload of data variables into memory if they are not
             already loaded.
           * 'all': All data variables will be concatenated.
           * list of str: The listed data variables will be concatenated, in
             addition to the 'minimal' data variables.
      coords : {'minimal', 'different', 'all' o list of str}, optional
          These coordinate variables will be concatenated together:
  
           * 'minimal': Only coordinates in which the dimension already appears
             are included.
           * 'different': Coordinates which are not equal (ignoring attributes)
             across all datasets are also concatenated (as well as all for which
             dimension already appears). Beware: this option may load the data
             payload of coordinate variables into memory if they are not already
             loaded.
           * 'all': All coordinate variables will be concatenated, except
             those corresponding to other dimensions.
           * list of str: The listed coordinate variables will be concatenated,
             in addition the 'minimal' coordinates.
      parallel : bool, optional
          If True, the open and preprocess steps of this function will be
          performed in parallel using ``dask.delayed``. Default is False.
      **kwargs : optional
          Additional arguments passed on to :py:func:`xarray.open_dataset`.
  
      Returns
      -------
      xarray.Dataset
  
      Notes
      -----
      ``open_mfdataset`` opens files with read-only access. When you modify values
      of a Dataset, even one linked to files on disk, only the in-memory copy you
      are manipulating in xarray is modified: the original file on disk is never
      touched.
  
      See Also
      --------
      auto_combine
      open_dataset
  
      References
      ----------
  
      .. [1] http://xarray.pydata.org/en/stable/dask.html
      .. [2] http://xarray.pydata.org/en/stable/dask.html#chunking-and-performance
      """  # noqa
      if isinstance(paths, str):
          if is_remote_uri(paths):
              raise ValueError(
                  'cannot do wild-card matching for paths that are remote URLs: '
                  '{!r}. Instead, supply paths as an explicit list of strings.'
                  .format(paths))
          paths = sorted(glob(paths))
      else:
          paths = [str(p) if isinstance(p, Path) else p for p in paths]
  
      if not paths:
          raise IOError('no files to open')
  
      # Coerce 1D input into ND to maintain backwards-compatible API until API
      # for N-D combine decided
      # (see https://github.com/pydata/xarray/pull/2553/#issuecomment-445892746)
      if concat_dim is None or concat_dim is _CONCAT_DIM_DEFAULT:
          concat_dims = concat_dim
      elif not isinstance(concat_dim, list):
          concat_dims = [concat_dim]
      else:
          concat_dims = concat_dim
      infer_order_from_coords = False
  
      # If infer_order_from_coords=True then this is unnecessary, but quick.
      # If infer_order_from_coords=False then this creates a flat list which is
      # easier to iterate over, while saving the originally-supplied structure
      combined_ids_paths, concat_dims = _infer_concat_order_from_positions(
          paths, concat_dims)
      ids, paths = (
          list(combined_ids_paths.keys()), list(combined_ids_paths.values()))
  
      open_kwargs = dict(engine=engine, chunks=chunks or {}, lock=lock,
                         autoclose=autoclose, **kwargs)
  
      if parallel:
          import dask
          # wrap the open_dataset, getattr, and preprocess with delayed
          open_ = dask.delayed(open_dataset)
          getattr_ = dask.delayed(getattr)
          if preprocess is not None:
              preprocess = dask.delayed(preprocess)
      else:
          open_ = open_dataset
          getattr_ = getattr
  
      datasets = [open_(p, **open_kwargs) for p in paths]
      file_objs = [getattr_(ds, '_file_obj') for ds in datasets]
      if preprocess is not None:
          datasets = [preprocess(ds) for ds in datasets]
  
      if parallel:
          # calling compute here will return the datasets/file_objs lists,
          # the underlying datasets will still be stored as dask arrays
          datasets, file_objs = dask.compute(datasets, file_objs)
  
      # Close datasets in case of a ValueError
      try:
          if infer_order_from_coords:
              # Discard ordering because it should be redone from coordinates
              ids = False
  
          combined = _auto_combine(
              datasets, concat_dims=concat_dims,
              compat=compat,
              data_vars=data_vars, coords=coords,
              infer_order_from_coords=infer_order_from_coords,
              ids=ids)
      except ValueError:
          for ds in datasets:
              ds.close()
          raise
  
      combined._file_obj = _MultiFileCloser(file_objs)
      combined.attrs = datasets[0].attrs
      return combined