diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 7fdb1f4d836..b878eb161a9 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -135,6 +135,9 @@ Bug fixes objects with data stored as ``dask`` arrays (:issue:`1529`). By `Joe Hamman `_. +- ``:py:meth:`~xarray.Dataset.__init__` raises a ``MergeError`` if an + coordinate shares a name with a dimension but is comprised of arbitrary + dimensions(:issue:`1120`). - :py:func:`~xarray.open_rasterio` method now skips rasterio.crs -attribute if it is none. By `Leevi Annala `_. diff --git a/xarray/core/merge.py b/xarray/core/merge.py index d156d0d78ef..f32c7bd82a4 100644 --- a/xarray/core/merge.py +++ b/xarray/core/merge.py @@ -365,6 +365,20 @@ def merge_data_and_coords(data, coords, compat='broadcast_equals', return merge_core(objs, compat, join, explicit_coords=explicit_coords) +def assert_valid_explicit_coords(variables, dims, explicit_coords): + """Validate explicit coordinate names/dims. + + Raise a MergeError if an explicit coord shares a name with a dimension + but is comprised of arbitrary dimensions. + """ + for coord_name in explicit_coords: + if coord_name in dims and variables[coord_name].dims != (coord_name,): + raise MergeError( + 'coordinate %s shares a name with a dataset dimension, but is ' + 'not a 1D variable along that dimension. This is disallowed ' + 'by the xarray data model.' % coord_name) + + def merge_core(objs, compat='broadcast_equals', join='outer', @@ -414,15 +428,16 @@ def merge_core(objs, coord_names, noncoord_names = determine_coords(coerced) - if explicit_coords is not None: - coord_names.update(explicit_coords) - priority_vars = _get_priority_vars(aligned, priority_arg, compat=compat) variables = merge_variables(expanded, priority_vars, compat=compat) assert_unique_multiindex_level_names(variables) dims = calculate_dimensions(variables) + if explicit_coords is not None: + assert_valid_explicit_coords(variables, dims, explicit_coords) + coord_names.update(explicit_coords) + for dim, size in dims.items(): if dim in variables: coord_names.add(dim) diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index b17aab47c12..2e8212d8685 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -246,6 +246,12 @@ def test_constructor(self): actual = Dataset({'z': expected['z']}) self.assertDatasetIdentical(expected, actual) + def test_constructor_invalid_dims(self): + # regression for GH1120 + with self.assertRaises(MergeError): + Dataset(data_vars=dict(v=('y', [1, 2, 3, 4])), + coords=dict(y=DataArray([.1, .2, .3, .4], dims='x'))) + def test_constructor_1d(self): expected = Dataset({'x': (['x'], 5.0 + np.arange(5))}) actual = Dataset({'x': 5.0 + np.arange(5)})