def add(self, name, auth_required=True, list_command=True, **validators):
        """Create a decorator that registers a handler and validation rules.

        Additional keyword arguments are treated as converters/validators to
        apply to tokens converting them to proper Python types.

        Requirements for valid handlers:

        - must accept a context argument as the first arg.
        - may not use variable keyword arguments, ``**kwargs``.
        - may use variable arguments ``*args`` *or* a mix of required and
          optional arguments.

        Decorator returns the unwrapped function so that tests etc can use the
        functions with values with correct python types instead of strings.

        :param string name: Name of the command being registered.
        :param bool auth_required: If authorization is required.
        :param bool list_command: If command should be listed in reflection.
        """

        def wrapper(func):
            if name in self.handlers:
                raise ValueError('%s already registered' % name)

            args, varargs, keywords, defaults = inspect.getargspec(func)
            defaults = dict(zip(args[-len(defaults or []):], defaults or []))

            if not args and not varargs:
                raise TypeError('Handler must accept at least one argument.')

            if len(args) > 1 and varargs:
                raise TypeError(
                    '*args may not be combined with regular arguments')

            if not set(validators.keys()).issubset(args):
                raise TypeError('Validator for non-existent arg passed')

            if keywords:
                raise TypeError('**kwargs are not permitted')

            def validate(*args, **kwargs):
                if varargs:
                    return func(*args, **kwargs)

                try:
                    callargs = inspect.getcallargs(func, *args, **kwargs)
                except __HOLE__:
                    raise exceptions.MpdArgError(
                        'wrong number of arguments for "%s"' % name)

                for key, value in callargs.items():
                    default = defaults.get(key, object())
                    if key in validators and value != default:
                        try:
                            callargs[key] = validators[key](value)
                        except ValueError:
                            raise exceptions.MpdArgError('incorrect arguments')

                return func(**callargs)

            validate.auth_required = auth_required
            validate.list_command = list_command
            self.handlers[name] = validate
            return func
        return wrapper
dataset/ETHPy150Open mopidy/mopidy/mopidy/mpd/protocol/__init__.py/Commands.add