Repository: pydata/xarray

Issue:
.rename() does not check conflict with multiindex level names
#### MCVE Code Sample

```python
>>> import xarray as xr
>>> ds = xr.Dataset({"x": 42}, {"level0": [0, 1], "level1": [3, 4]}).set_index(mindex=["level0", "level1"])
>>> ds
<xarray.Dataset>
Dimensions:  (mindex: 2)
Coordinates:
  * mindex   (mindex) MultiIndex
  - level0   (mindex) int64 0 1
  - level1   (mindex) int64 3 4
Data variables:
    x        int64 42
>>> ds.rename({"x": "level0"})
<xarray.Dataset>
Dimensions:  (mindex: 2)
Coordinates:
  * mindex   (mindex) MultiIndex
  - level0   (mindex) int64 0 1
  - level1   (mindex) int64 3 4
Data variables:
    level0   int64 42
```

#### Expected Output
raise a ValueError("conflicting Multiindex names ...")

#### Problem Description
Using .rename() you can get into a situation where you have a data variable or coordinate with the same name as a multi-index level name.

#### Output of ``xr.show_versions()``
<details>

INSTALLED VERSIONS
------------------
commit: b3d3b4480b7fb63402eb6c02103bb8d6c7dbf93a
python: 3.8.0 | packaged by conda-forge | (default, Nov 22 2019, 19:11:38)
[GCC 7.3.0]
python-bits: 64
OS: Linux
OS-release: 4.4.0-18362-Microsoft
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8
libhdf5: None
libnetcdf: None

xarray: 0.14.1+36.gb3d3b44
pandas: 0.25.3
numpy: 1.18.0
scipy: None
netCDF4: None
pydap: None
h5netcdf: None
h5py: None
Nio: None
zarr: None
cftime: None
nc_time_axis: None
PseudoNetCDF: None
rasterio: None
cfgrib: None
iris: None
bottleneck: None
dask: 2.9.1
distributed: 2.9.1
matplotlib: None
cartopy: None
seaborn: None
numbagg: None
setuptools: 42.0.2.post20191201
pip: 19.3.1
conda: None
pytest: 5.3.2
IPython: None
sphinx: None

</details>


Discussion:
hazbottles: > 
> 
> Thanks, @hazbottles, for your contribution.
> 
> This looks nice.
> Please add your contribution to what's new in
> /doc/whats-new.rst

Done.

Patch:
diff --git a/doc/whats-new.rst b/doc/whats-new.rst
index 00d1c507..70853dbb 100644
--- a/doc/whats-new.rst
+++ b/doc/whats-new.rst
@@ -62,6 +62,8 @@ Bug fixes
   By `Tom Augspurger <https://github.com/TomAugspurger>`_.
 - Ensure :py:meth:`Dataset.quantile`, :py:meth:`DataArray.quantile` issue the correct error
   when ``q`` is out of bounds (:issue:`3634`) by `Mathias Hauser <https://github.com/mathause>`_.
+- :py:meth:`Dataset.rename`, :py:meth:`DataArray.rename` now check for conflicts with
+  MultiIndex level names.
 
 Documentation
 ~~~~~~~~~~~~~
diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py
index 6be06fed..032c66d3 100644
--- a/xarray/core/dataset.py
+++ b/xarray/core/dataset.py
@@ -89,7 +89,13 @@ from .utils import (
     is_scalar,
     maybe_wrap_array,
 )
-from .variable import IndexVariable, Variable, as_variable, broadcast_variables
+from .variable import (
+    IndexVariable,
+    Variable,
+    as_variable,
+    broadcast_variables,
+    assert_unique_multiindex_level_names,
+)
 
 if TYPE_CHECKING:
     from ..backends import AbstractDataStore, ZarrStore
@@ -2780,6 +2786,7 @@ class Dataset(Mapping, ImplementsDatasetReduce, DataWithCoords):
         variables, coord_names, dims, indexes = self._rename_all(
             name_dict=name_dict, dims_dict=name_dict
         )
+        assert_unique_multiindex_level_names(variables)
         return self._replace(variables, coord_names, dims=dims, indexes=indexes)
 
     def rename_dims(


Test patch:
diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py
index 7db19116..edda4cb2 100644
--- a/xarray/tests/test_dataset.py
+++ b/xarray/tests/test_dataset.py
@@ -2461,6 +2461,14 @@ class TestDataset:
         with pytest.raises(ValueError):
             original.rename_vars(names_dict_bad)
 
+    def test_rename_multiindex(self):
+        mindex = pd.MultiIndex.from_tuples(
+            [([1, 2]), ([3, 4])], names=["level0", "level1"]
+        )
+        data = Dataset({}, {"x": mindex})
+        with raises_regex(ValueError, "conflicting MultiIndex"):
+            data.rename({"x": "level0"})
+
     @requires_cftime
     def test_rename_does_not_change_CFTimeIndex_type(self):
         # make sure CFTimeIndex is not converted to DatetimeIndex #3522