# Buggy code
def deep_align(list_of_variable_maps, join="outer", copy=True, indexes=None):
    """Align objects, recursing into dictionary values."""
    if indexes is None:
        indexes = {}

    # We use keys to identify arguments to align. Integers indicate single
    # arguments, while (int, variable_name) pairs indicate variables in ordered
    # dictionaries.
    keys = []
    out = []
    targets = []
    sentinel = object()
    for n, variables in enumerate(list_of_variable_maps):
        if is_alignable(variables):
            keys.append(n)
            targets.append(variables)
            out.append(sentinel)
        elif is_dict_like(variables):
            for k, v in variables.items():
                if is_alignable(v) and k not in indexes:
                    # don't align dict-like variables that are already fixed
                    # indexes: we might be overwriting these index variables
                    keys.append((n, k))
                    targets.append(v)
            out.append(OrderedDict(variables))
        else:
            out.append(variables)

    aligned = partial_align(*targets, join=join, copy=copy, indexes=indexes)

    for key, aligned_obj in zip(keys, aligned):
        if isinstance(key, tuple):
            n, k = key
            out[n][k] = aligned_obj
        else:
            out[key] = aligned_obj

    # something went wrong: we should have replaced all sentinel values
    assert all(arg is not sentinel for arg in out)

    return out


# 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 deep_align(
    list_of_variable_maps,
    join="outer",
    copy=True,
    indexes=None,
    skip_single_target=False,
):
    """Align objects, recursing into dictionary values."""
    if indexes is None:
        indexes = {}

    # We use keys to identify arguments to align. Integers indicate single
    # arguments, while (int, variable_name) pairs indicate variables in ordered
    # dictionaries.
    keys = []
    out = []
    targets = []
    sentinel = object()
    for n, variables in enumerate(list_of_variable_maps):
        if is_alignable(variables):
            keys.append(n)
            targets.append(variables)
            out.append(sentinel)
        elif is_dict_like(variables):
            for k, v in variables.items():
                if is_alignable(v) and k not in indexes:
                    # don't align dict-like variables that are already fixed
                    # indexes: we might be overwriting these index variables
                    keys.append((n, k))
                    targets.append(v)
            out.append(OrderedDict(variables))
        else:
            out.append(variables)

    aligned = partial_align(
        *targets,
        join=join,
        copy=copy,
        indexes=indexes,
        skip_single_target=skip_single_target,
    )

    for key, aligned_obj in zip(keys, aligned):
        if isinstance(key, tuple):
            n, k = key
            out[n][k] = aligned_obj
        else:
            out[key] = aligned_obj

    # something went wrong: we should have replaced all sentinel values
    assert all(arg is not sentinel for arg in out)

    return out