# Buggy code
def _reindex_non_unique(self, target):
    """
    Create a new index with target's values (move/add/delete values as
    necessary) use with non-unique Index and a possibly non-unique target.

    Parameters
    ----------
    target : an iterable

    Returns
    -------
    new_index : pd.Index
        Resulting index.
    indexer : np.ndarray or None
        Indices of output values in original index.

    """
    target = ensure_index(target)
    indexer, missing = self.get_indexer_non_unique(target)
    check = indexer != -1
    new_labels = self.take(indexer[check])
    new_indexer = None

    if len(missing):
        length = np.arange(len(indexer))

        missing = ensure_platform_int(missing)
        missing_labels = target.take(missing)
        missing_indexer = ensure_int64(length[~check])
        cur_labels = self.take(indexer[check]).values
        cur_indexer = ensure_int64(length[check])

        new_labels = np.empty(tuple([len(indexer)]), dtype=object)
        new_labels[cur_indexer] = cur_labels
        new_labels[missing_indexer] = missing_labels

        # a unique indexer
        if target.is_unique:
            # see GH5553, make sure we use the right indexer
            new_indexer = np.arange(len(indexer))
            new_indexer[cur_indexer] = np.arange(len(cur_labels))
            new_indexer[missing_indexer] = -1

        # we have a non_unique selector, need to use the original
        # indexer here
        else:
            # need to retake to have the same size as the indexer
            indexer[~check] = -1

            # reset the new indexer to account for the new size
            new_indexer = np.arange(len(self.take(indexer)))
            new_indexer[~check] = -1

    if isinstance(self, ABCMultiIndex):
        new_index = type(self).from_tuples(new_labels, names=self.names)
    else:
        new_index = Index(new_labels, name=self.name)
    return new_index, indexer, new_indexer


# Traceback (TypeError)
In [2]: s = pd.Series(0, index=pd.MultiIndex.from_product([[0], [1,2]]))

In [3]: s.loc[[]]
Out[3]: Series([], dtype: int64)

In [4]: s = pd.Series(0, index=pd.MultiIndex.from_product([[0], [1,1]]))

In [5]: s.loc[[]]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-f9b6211189ca> in <module>()
----> 1 s.loc[[]]

/home/pietro/nobackup/repo/pandas/pandas/core/indexing.py in __getitem__(self, key)
1304             return self._getitem_tuple(key)
1305         else:
-> 1306             return self._getitem_axis(key, axis=0)
1307
1308     def _getitem_axis(self, key, axis=0):

/home/pietro/nobackup/repo/pandas/pandas/core/indexing.py in _getitem_axis(self, key, axis)
1464                     raise ValueError('Cannot index with multidimensional key')
1465
-> 1466                 return self._getitem_iterable(key, axis=axis)
1467
1468             # nested tuple slicing

/home/pietro/nobackup/repo/pandas/pandas/core/indexing.py in _getitem_iterable(self, key, axis)
1095
1096                 new_target, indexer, new_indexer = labels._reindex_non_unique(
-> 1097                     keyarr)
1098
1099                 if new_indexer is not None:

/home/pietro/nobackup/repo/pandas/pandas/indexes/base.py in _reindex_non_unique(self, target)
2497                 new_indexer[~check] = -1
2498
-> 2499         new_index = self._shallow_copy_with_infer(new_labels, freq=None)
2500         return new_index, indexer, new_indexer
2501

/home/pietro/nobackup/repo/pandas/pandas/indexes/multi.py in _shallow_copy_with_infer(self, values, **kwargs)
393
394     def _shallow_copy_with_infer(self, values=None, **kwargs):
--> 395         return self._shallow_copy(values, **kwargs)
396
397     @Appender(_index_shared_docs['_shallow_copy'])

/home/pietro/nobackup/repo/pandas/pandas/indexes/multi.py in _shallow_copy(self, values, **kwargs)
402             # discards freq
403             kwargs.pop('freq', None)
--> 404             return MultiIndex.from_tuples(values, **kwargs)
405         return self.view()
406

/home/pietro/nobackup/repo/pandas/pandas/indexes/multi.py in from_tuples(cls, tuples, sortorder, names)
889         if len(tuples) == 0:
890             # I think this is right? Not quite sure...
--> 891             raise TypeError('Cannot infer number of levels from empty list')
892
893         if isinstance(tuples, (np.ndarray, Index)):

TypeError: Cannot infer number of levels from empty list

# Fixed code
def _reindex_non_unique(self, target):
    """
    Create a new index with target's values (move/add/delete values as
    necessary) use with non-unique Index and a possibly non-unique target.

    Parameters
    ----------
    target : an iterable

    Returns
    -------
    new_index : pd.Index
        Resulting index.
    indexer : np.ndarray or None
        Indices of output values in original index.

    """
    target = ensure_index(target)
    if len(target) == 0:
        # GH#13691
        return self[:0], np.array([], dtype=np.intp), None

    indexer, missing = self.get_indexer_non_unique(target)
    check = indexer != -1
    new_labels = self.take(indexer[check])
    new_indexer = None

    if len(missing):
        length = np.arange(len(indexer))

        missing = ensure_platform_int(missing)
        missing_labels = target.take(missing)
        missing_indexer = ensure_int64(length[~check])
        cur_labels = self.take(indexer[check]).values
        cur_indexer = ensure_int64(length[check])

        new_labels = np.empty(tuple([len(indexer)]), dtype=object)
        new_labels[cur_indexer] = cur_labels
        new_labels[missing_indexer] = missing_labels

        # a unique indexer
        if target.is_unique:
            # see GH5553, make sure we use the right indexer
            new_indexer = np.arange(len(indexer))
            new_indexer[cur_indexer] = np.arange(len(cur_labels))
            new_indexer[missing_indexer] = -1

        # we have a non_unique selector, need to use the original
        # indexer here
        else:
            # need to retake to have the same size as the indexer
            indexer[~check] = -1

            # reset the new indexer to account for the new size
            new_indexer = np.arange(len(self.take(indexer)))
            new_indexer[~check] = -1

    if isinstance(self, ABCMultiIndex):
        new_index = type(self).from_tuples(new_labels, names=self.names)
    else:
        new_index = Index(new_labels, name=self.name)
    return new_index, indexer, new_indexer