def slice_indexer(self, start=None, end=None, step=None, kind=None):
<EOL>if isinstance(start, time) and isinstance(end, time):<EOL><INDENT>if step is not None and step != <NUM_LIT:1>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return self.indexer_between_time(start, end)<EOL><DEDENT>if isinstance(start, time) or isinstance(end, time):<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>try:<EOL><INDENT>return Index.slice_indexer(self, start, end, step, kind=kind)<EOL><DEDENT>except KeyError:<EOL><INDENT>if ((start is None or isinstance(start, str)) and<EOL>(end is None or isinstance(end, str))):<EOL><INDENT>mask = True<EOL>if start is not None:<EOL><INDENT>start_casted = self._maybe_cast_slice_bound(<EOL>start, '<STR_LIT:left>', kind)<EOL>mask = start_casted <= self<EOL><DEDENT>if end is not None:<EOL><INDENT>end_casted = self._maybe_cast_slice_bound(<EOL>end, '<STR_LIT:right>', kind)<EOL>mask = (self <= end_casted) & mask<EOL><DEDENT>indexer = mask.nonzero()[<NUM_LIT:0>][::step]<EOL>if len(indexer) == len(self):<EOL><INDENT>return slice(None)<EOL><DEDENT>else:<EOL><INDENT>return indexer<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>
Return indexer for specified label slice.
Index.slice_indexer, customized to handle time slicing.

In addition to functionality provided by Index.slice_indexer, does the
following:

- if both `start` and `end` are instances of `datetime.time`, it
  invokes `indexer_between_time`
- if `start` and `end` are both either string or None perform
  value-based selection in non-monotonic cases.