# Buggy code
def _getitem_lowerdim(self, tup):
    from pandas.core.frame import DataFrame

    ax0 = self.obj._get_axis(0)
    # a bit kludgy
    if isinstance(ax0, MultiIndex):
        try:
            return self._get_label(tup, axis=0)
        except TypeError:
            # slices are unhashable
            pass
        except Exception:
            if tup[0] not in ax0:
                raise

    # to avoid wasted computation
    # df.ix[d1:d2, 0] -> columns first (True)
    # df.ix[0, ['C', 'B', A']] -> rows first (False)
    for i, key in enumerate(tup):
        if _is_label_like(key):
            section = self._getitem_axis(key, axis=i)

            # might have been a MultiIndex
            if section.ndim == self.ndim:
                new_key = tup[:i] + (_NS,) + tup[i + 1 :]
                # new_key = tup[:i] + tup[i+1:]
            else:
                new_key = tup[:i] + tup[i + 1 :]

                # unfortunately need an odious kludge here because of
                # DataFrame transposing convention
                if isinstance(section, DataFrame) and i > 0 and len(new_key) == 2:
                    a, b = new_key
                    new_key = b, a

                if len(new_key) == 1:
                    (new_key,) = new_key

            return section.ix[new_key]

    raise IndexingError("not applicable")


# Traceback (TypeError)
In [20]: df
Out[20]:
value
id
t1 a   1
b   2
c   3
t2 a   7
b   8

In [21]: df.ix[:, 'value']
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/home/wesm/Dropbox/book/svn/<ipython-input-21-7d089958dc90> in <module>()
----> 1 df.ix[:, 'value']

/home/wesm/code/pandas/pandas/core/indexing.pyc in __getitem__(self, key)
28                 pass
29
---> 30             return self._getitem_tuple(key)
31         else:
32             return self._getitem_axis(key, axis=0)

/home/wesm/code/pandas/pandas/core/indexing.pyc in _getitem_tuple(self, tup)
97     def _getitem_tuple(self, tup):
98         try:
---> 99             return self._getitem_lowerdim(tup)
100         except IndexingError:
101             pass

/home/wesm/code/pandas/pandas/core/indexing.pyc in _getitem_lowerdim(self, tup)
126                 pass
127             except Exception:
--> 128                 if tup[0] not in ax0:
129                     raise
130

/home/wesm/code/pandas/pandas/core/index.pyc in __contains__(self, key)
209
210     def __contains__(self, key):
--> 211         return key in self._engine
212
213     def __hash__(self):

/home/wesm/code/pandas/pandas/_engines.so in pandas._engines.DictIndexEngine.__contains__ (pandas/src/engines.c:1958)()

TypeError: unhashable type

# Fixed code
def _getitem_lowerdim(self, tup):
    from pandas.core.frame import DataFrame

    ax0 = self.obj._get_axis(0)
    # a bit kludgy
    if isinstance(ax0, MultiIndex):
        try:
            return self._get_label(tup, axis=0)
        except TypeError:
            # slices are unhashable
            pass
        except Exception:
            if isinstance(tup[0], slice):
                raise IndexingError
            if tup[0] not in ax0:
                raise

    # to avoid wasted computation
    # df.ix[d1:d2, 0] -> columns first (True)
    # df.ix[0, ['C', 'B', A']] -> rows first (False)
    for i, key in enumerate(tup):
        if _is_label_like(key):
            section = self._getitem_axis(key, axis=i)

            # might have been a MultiIndex
            if section.ndim == self.ndim:
                new_key = tup[:i] + (_NS,) + tup[i + 1 :]
                # new_key = tup[:i] + tup[i+1:]
            else:
                new_key = tup[:i] + tup[i + 1 :]

                # unfortunately need an odious kludge here because of
                # DataFrame transposing convention
                if isinstance(section, DataFrame) and i > 0 and len(new_key) == 2:
                    a, b = new_key
                    new_key = b, a

                if len(new_key) == 1:
                    (new_key,) = new_key

            return section.ix[new_key]

    raise IndexingError("not applicable")