# Buggy code
def partial_align(*objects, **kwargs):
    """partial_align(*objects, join='inner', copy=True, indexes=None,
                     exclude=set())

    Like align, but don't align along dimensions in exclude. Any indexes
    explicitly provided with the `indexes` argument should be used in preference
    to the aligned indexes.

    Not public API.
    """
    join = kwargs.pop("join", "inner")
    copy = kwargs.pop("copy", True)
    indexes = kwargs.pop("indexes", None)
    exclude = kwargs.pop("exclude", None)
    if exclude is None:
        exclude = set()
    if kwargs:
        raise TypeError("align() got unexpected keyword arguments: %s" % list(kwargs))

    joined_indexes = _join_indexes(join, objects, exclude=exclude)
    if indexes is not None:
        joined_indexes.update(indexes)

    result = []
    for obj in objects:
        valid_indexers = dict(
            (k, v) for k, v in joined_indexes.items() if k in obj.dims
        )
        result.append(obj.reindex(copy=copy, **valid_indexers))
    return tuple(result)


# Traceback (InvalidIndexError)
InvalidIndexError                         Traceback (most recent call last)
<ipython-input-5-50e97aa6cb4e> in <module>()
4 ds = xarray.Dataset({'data': (['dim0', 'dim1'], np.empty((5,10)))},
5                     coords={'dim0': [0, 1, 2, 0, 1], 'dim1': list(range(10))})
----> 6 ds['dim0'] = list(range(5))

/home/rotis/anaconda/envs/calphadpy3/lib/python3.5/site-packages/xarray/core/dataset.py in __setitem__(self, key, value)
536             raise NotImplementedError('cannot yet use a dictionary as a key '
537                                       'to set Dataset values')
--> 538         self.update({key: value})
539
540     def __delitem__(self, key):

/home/rotis/anaconda/envs/calphadpy3/lib/python3.5/site-packages/xarray/core/dataset.py in update(self, other, inplace)
1434             dataset.
1435         """
-> 1436         variables, coord_names, dims = dataset_update_method(self, other)
1437
1438         return self._replace_vars_and_dims(variables, coord_names, dims,

/home/rotis/anaconda/envs/calphadpy3/lib/python3.5/site-packages/xarray/core/merge.py in dataset_update_method(dataset, other)
490     priority_arg = 1
491     indexes = dataset.indexes
--> 492     return merge_core(objs, priority_arg=priority_arg, indexes=indexes)

/home/rotis/anaconda/envs/calphadpy3/lib/python3.5/site-packages/xarray/core/merge.py in merge_core(objs, compat, join, priority_arg, explicit_coords, indexes)
371
372     coerced = coerce_pandas_values(objs)
--> 373     aligned = deep_align(coerced, join=join, copy=False, indexes=indexes)
374     expanded = expand_variable_dicts(aligned)
375

/home/rotis/anaconda/envs/calphadpy3/lib/python3.5/site-packages/xarray/core/alignment.py in deep_align(list_of_variable_maps, join, copy, indexes)
146             out.append(variables)
147
--> 148     aligned = partial_align(*targets, join=join, copy=copy, indexes=indexes)
149
150     for key, aligned_obj in zip(keys, aligned):

/home/rotis/anaconda/envs/calphadpy3/lib/python3.5/site-packages/xarray/core/alignment.py in partial_align(*objects, **kwargs)
109         valid_indexers = dict((k, v) for k, v in joined_indexes.items()
110                               if k in obj.dims)
--> 111         result.append(obj.reindex(copy=copy, **valid_indexers))
112     return tuple(result)
113

/home/rotis/anaconda/envs/calphadpy3/lib/python3.5/site-packages/xarray/core/dataset.py in reindex(self, indexers, method, tolerance, copy, **kw_indexers)
1216
1217         variables = alignment.reindex_variables(
-> 1218             self.variables, self.indexes, indexers, method, tolerance, copy=copy)
1219         return self._replace_vars_and_dims(variables)
1220

/home/rotis/anaconda/envs/calphadpy3/lib/python3.5/site-packages/xarray/core/alignment.py in reindex_variables(variables, indexes, indexers, method, tolerance, copy)
218             target = utils.safe_cast_to_index(indexers[name])
219             indexer = index.get_indexer(target, method=method,
--> 220                                         **get_indexer_kwargs)
221
222             to_shape[name] = len(target)

/home/rotis/anaconda/envs/calphadpy3/lib/python3.5/site-packages/pandas/indexes/base.py in get_indexer(self, target, method, limit, tolerance)
2011
2012         if not self.is_unique:
-> 2013             raise InvalidIndexError('Reindexing only valid with uniquely'
2014                                     ' valued Index objects')
2015

InvalidIndexError: Reindexing only valid with uniquely valued Index objects

# Fixed code
def partial_align(*objects, **kwargs):
    """partial_align(*objects, join='inner', copy=True, indexes=None,
                     exclude=set())

    Like align, but don't align along dimensions in exclude. Any indexes
    explicitly provided with the `indexes` argument should be used in preference
    to the aligned indexes.

    Not public API.
    """
    join = kwargs.pop("join", "inner")
    copy = kwargs.pop("copy", True)
    indexes = kwargs.pop("indexes", None)
    exclude = kwargs.pop("exclude", None)
    if exclude is None:
        exclude = set()
    skip_single_target = kwargs.pop("skip_single_target", False)
    if kwargs:
        raise TypeError("align() got unexpected keyword arguments: %s" % list(kwargs))

    if len(objects) == 1:
        (obj,) = objects
        if indexes is None or (
            skip_single_target
            and all(
                obj.indexes[k].equals(v) for k, v in indexes.items() if k in obj.indexes
            )
        ):
            # We don't need to align, so don't bother with reindexing, which
            # fails for non-unique indexes.
            # `skip_single_target` is a hack so we can skip alignment of a
            # single object in merge.
            return (obj.copy() if copy else obj,)

    joined_indexes = _join_indexes(join, objects, exclude=exclude)
    if indexes is not None:
        joined_indexes.update(indexes)

    result = []
    for obj in objects:
        valid_indexers = dict(
            (k, v) for k, v in joined_indexes.items() if k in obj.dims
        )
        result.append(obj.reindex(copy=copy, **valid_indexers))

    return tuple(result)