diff --git a/xarray/backends/api.py b/xarray/backends/api.py index 3cd62e8264a..5f88783bb2e 100644 --- a/xarray/backends/api.py +++ b/xarray/backends/api.py @@ -10,7 +10,8 @@ from .. import Dataset, backends, conventions from ..core import indexing -from ..core.combine import _auto_combine, _infer_concat_order_from_positions +from ..core.combine import ( + _CONCAT_DIM_DEFAULT, _auto_combine, _infer_concat_order_from_positions) from ..core.pycompat import basestring, path_type from ..core.utils import close_on_error, is_grib_path, is_remote_uri from .common import ArrayWriter @@ -483,9 +484,6 @@ def close(self): f.close() -_CONCAT_DIM_DEFAULT = '__infer_concat_dim__' - - 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', @@ -606,7 +604,7 @@ def open_mfdataset(paths, chunks=None, concat_dim=_CONCAT_DIM_DEFAULT, # 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 == _CONCAT_DIM_DEFAULT: + 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] diff --git a/xarray/core/combine.py b/xarray/core/combine.py index abb2e2c1306..e552d8d900c 100644 --- a/xarray/core/combine.py +++ b/xarray/core/combine.py @@ -368,7 +368,7 @@ def _auto_concat(datasets, dim=None, data_vars='all', coords='different'): return concat(datasets, dim=dim, data_vars=data_vars, coords=coords) -_CONCAT_DIM_DEFAULT = '__infer_concat_dim__' +_CONCAT_DIM_DEFAULT = utils.ReprObject('') def _infer_concat_order_from_positions(datasets, concat_dims): diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index 02ac06903c9..57e875bb563 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -2367,6 +2367,29 @@ def test_open_single_dataset(self): with open_mfdataset([tmp], concat_dim=dim) as actual: assert_identical(expected, actual) + def test_open_multi_dataset(self): + # Test for issue GH #1988 and #2647. This makes sure that the + # concat_dim is utilized when specified in open_mfdataset(). + # The additional wrinkle is to ensure that a length greater + # than one is tested as well due to numpy's implicit casting + # of 1-length arrays to booleans in tests, which allowed + # #2647 to still pass the test_open_single_dataset(), + # which is itself still needed as-is because the original + # bug caused one-length arrays to not be used correctly + # in concatenation. + rnddata = np.random.randn(10) + original = Dataset({'foo': ('x', rnddata)}) + dim = DataArray([100, 150], name='baz', dims='baz') + expected = Dataset({'foo': (('baz', 'x'), + np.tile(rnddata[np.newaxis, :], (2, 1)))}, + {'baz': [100, 150]}) + with create_tmp_file() as tmp1, \ + create_tmp_file() as tmp2: + original.to_netcdf(tmp1) + original.to_netcdf(tmp2) + with open_mfdataset([tmp1, tmp2], concat_dim=dim) as actual: + assert_identical(expected, actual) + def test_dask_roundtrip(self): with create_tmp_file() as tmp: data = create_test_data()