def _set_names(self, names, level=None, validate=True):
<EOL>if names is not None and not is_list_like(names):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>names = list(names)<EOL>if validate and level is not None and len(names) != len(level):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if validate and level is None and len(names) != self.nlevels:<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>if level is None:<EOL><INDENT>level = range(self.nlevels)<EOL><DEDENT>else:<EOL><INDENT>level = [self._get_level_number(l) for l in level]<EOL><DEDENT>for l, name in zip(level, names):<EOL><INDENT>if name is not None:<EOL><INDENT>if not is_hashable(name):<EOL><INDENT>raise TypeError('<STR_LIT>'<EOL>.format(self.__class__.__name__))<EOL><DEDENT><DEDENT>self.levels[l].rename(name, inplace=True)<EOL><DEDENT>
Set new names on index. Each name has to be a hashable type.

Parameters
----------
values : str or sequence
    name(s) to set
level : int, level name, or sequence of int/level names (default None)
    If the index is a MultiIndex (hierarchical), level(s) to set (None
    for all levels).  Otherwise level must be None
validate : boolean, default True
    validate that the names match level lengths

Raises
------
TypeError if each name is not hashable.

Notes
-----
sets names on levels. WARNING: mutates!

Note that you generally want to set this *after* changing levels, so
that it only acts on copies