Args:
        func (function): Function defining this option
        *args: Optional extra short flag name
        **attrs: Optional attr overrides provided by caller

    Returns:
        function: Click decorator
347123
def option(func, *args, **attrs):
    
    if click is None:
        return func

    def decorator(f):
        name = attrs.pop("name", func.__name__.replace("_", "-"))
        attrs.setdefault("help", func.__doc__)
        attrs.setdefault("required", False)
        if not attrs.get("is_flag"):
            attrs.setdefault("show_default", True)
            attrs.setdefault("metavar", name.replace("-", "_").upper())
            attrs.setdefault("type", str)
        if not name.startswith("-"):
            name = "--%s" % name
        return click.option(name, *args, **attrs)(f)

    return decorator
348633
def decorator(self, func):
        
        if inspect.isfunction(func):
            func._methodview = self
        elif inspect.ismethod(func):
            func.__func__._methodview = self
        else:
            raise AssertionError('Can only decorate function and methods, {} given'.format(func))
        return func
863773
def function_arguments(func):
    
    if getattr(inspect, 'signature', None) is None:
        return list(inspect.getargspec(func).args)
    else:
        return list(inspect.signature(func).parameters.keys())
75709
def argument(*args, **kwargs):
    
    def decorator(f):
        if not hasattr(f, '_arguments'):
            f._arguments = []
        if not hasattr(f, '_argnames'):
            f._argnames = []
        f._arguments.append((args, kwargs))
        f._argnames.append(_get_dest(*args, **kwargs))
        return f
    return decorator
457656
def decorate(func, caller):
    
    evaldict = dict(_call_=caller, _func_=func)
    fun = FunctionMaker.create(
        func, "return _call_(_func_, %(shortsignature)s)",
        evaldict, __wrapped__=func)
    if hasattr(func, '__qualname__'):
        fun.__qualname__ = func.__qualname__
    return fun
202950
def self_if_parameters(func):
    
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        result = func(self, *args, **kwargs)
        if args or kwargs:
            return self
        else:
            return result
    return wrapper
1240031
def compile_func(arg_names, statements, name='_the_func', debug=False):
    
    func_def = ast.FunctionDef(
        name=name,
        args=ast.arguments(
            args=[ast.arg(arg=n, annotation=None) for n in arg_names],
            kwonlyargs=[],
            kw_defaults=[],
            defaults=[ex_literal(None) for _ in arg_names],
        ),
        body=statements,
        decorator_list=[],
    )

    mod = ast.Module([func_def])
    ast.fix_missing_locations(mod)

    prog = compile(mod, '<generated>', 'exec')

    # Debug: show bytecode.
    if debug:
        dis.dis(prog)
        for const in prog.co_consts:
            if isinstance(const, types.CodeType):
                dis.dis(const)

    the_locals = {}
    exec(prog, {}, the_locals)
    return the_locals[name]
714271
def argv_flag_dec(*argin, **kwargs):
    
    kwargs = kwargs.copy()
    kwargs['default'] = kwargs.get('default', False)
    from utool import util_decor
    @util_decor.ignores_exc_tb(outer_wrapper=False)
    def wrap_argv_flag_dec(func):
        return __argv_flag_dec(func, **kwargs)

    assert len(argin) < 2, 'specify 0 or 1 args'

    if len(argin) == 1 and util_type.is_funclike(argin[0]):
        func = argin[0]
        return wrap_argv_flag_dec(func)
    else:
        return wrap_argv_flag_dec
197440
def setter(self, func):
        
        if not callable(func):
            raise TypeError('setter must be callable function')
        if hasattr(func, '__code__') and func.__code__.co_argcount != 2:
            raise TypeError('setter must be a function with two arguments')
        if func.__name__ != self.name:
            raise TypeError('setter function must have same name as getter')
        self._set_func = func
        return self
689780
def describe_arguments(func):
    

    argspec = inspect.getargspec(func)
    # we should probably raise an exception somewhere if func includes **kwargs
    if argspec.defaults:
        positional_args = argspec.args[:-len(argspec.defaults)]
        keyword_names = argspec.args[-len(argspec.defaults):]
        for arg, default in zip(keyword_names, argspec.defaults):
            yield ('--{}'.format(arg),), {'default': default}
    else:
        positional_args = argspec.args

    for arg in positional_args:
        yield (arg,), {}
    if argspec.varargs:
        yield (argspec.varargs,), {'nargs': '*'}
683842
def _validate_func_args(func, kwargs):
    """"""

    args, varargs, varkw, defaults = inspect.getargspec(func)
    if set(kwargs.keys()) != set(args[1:]): # chop off self
        raise TypeError("decorator kwargs do not match %s()'s kwargs"
                        % func.__name__)
621074
def make_context_aware(func, numargs):
    
    try:
        if inspect.ismethod(func):
            arg_count = len(inspect.getargspec(func).args) - 1
        elif inspect.isfunction(func):
            arg_count = len(inspect.getargspec(func).args)
        elif inspect.isclass(func):
            arg_count = len(inspect.getargspec(func.__init__).args) - 1
        else:
            arg_count = len(inspect.getargspec(func.__call__).args) - 1
    except TypeError:
        arg_count = numargs

    if arg_count <= numargs:
        def normalized(*args):
            return func(*args[:-1])

        return normalized

    return func
827076
def __get_dynamic_attr(self, attname, arg, default=None):
        
        try:
            attr = getattr(self, attname)
        except AttributeError:
            return default
        if callable(attr):
            # Check func_code.co_argcount rather than try/excepting the
            # function and catching the TypeError, because something inside
            # the function may raise the TypeError. This technique is more
            # accurate.
            if hasattr(attr, 'func_code'):
                argcount = attr.func_code.co_argcount
            else:
                argcount = attr.__call__.func_code.co_argcount
            if argcount == 2: # one argument is 'self'
                return attr(arg)
            else:
                return attr()
        return attr
1191712
def arg(*args, **kwargs):
    
    def decorate(func):
        """
        Decorate
        """
        # we'll set the command name with the passed cmd_name argument, if
        # exist, else the command name will be the function name
        func.__cmd_name__ = kwargs.pop(
            'cmd_name', getattr(func, '__cmd_name__', func.__name__))
        # retrieve the class (SillyClass)
        func.__cls__ = utils.check_class()
        if not hasattr(func, '__arguments__'):
            # if the funcion hasn't the __arguments__ yet, we'll setup them
            # using get_functarguments.
            func.__arguments__ = utils.get_functarguments(func)
        if len(args) or len(kwargs):
            # if we have some argument or keyword argument
            # we'll try to get the destination name from the kwargs ('dest')
            # else we'll use the last arg name as destination
            arg_name = kwargs.get(
                'dest', args[-1].lstrip('-').replace('-', '_'))
            try:
                # we try to get the command index.
                idx = func.__named__.index(arg_name)
                # and delete it from the named list
                del func.__named__[idx]
                # and delete it from the arguments list
                del func.__arguments__[idx]
            except ValueError:
                pass
            # append the args and kwargs to the function arguments list
            func.__arguments__.append((args, kwargs,))
        if func.__cls__ is None and isinstance(func, types.FunctionType):
            # if the function don't have a class and is a FunctionType
            # we'll add it directly to he commands list.
            ap_ = ArgParseInator(skip_init=True)
            if func.__cmd_name__ not in ap_.commands:
                # we'll add it if not exists
                ap_.commands[func.__cmd_name__] = func
        return func
    return decorate
676044
def accepts_kwarg(func, kwarg):
    
    signature = inspect.signature(func)
    try:
        signature.bind_partial(**{kwarg: None})
        return True
    except TypeError:
        return False
934485
def check_types(func):
    
    call = PythonCall(func)

    @wraps(func)
    def decorator(*args, **kwargs):
        parameters = call.bind(args, kwargs)
        for arg_name, expected_type in func.__annotations__.items():
            if not isinstance(parameters[arg_name], expected_type):
                raise TypeError("{} must be a {}".format(
                    arg_name, expected_type))
        return call.apply(args, kwargs)
    return decorator
604434
def decorate_method(cls, func):
        
        func_args = [arg for arg in function_arguments(func) if arg != 'self']
        method_return_types = \
            Endpoint._parse_function_return_types_from_doc(func.__doc__)
        name = '%s.%s' % (cls.path, func.__name__)

        @wraps(func)
        def method_decorator(self, *args, **kwargs):
            for i in range(len(args)):
                kwargs[func_args[i]] = args[i]

            api_call = self.connection._pre_process_call(
                name, endpoint_params=kwargs)
            try:
                data = func(**kwargs)
            except RestException as e:
                api_call.error = e
                raise e

            except Exception as e:
                call_queue = self.connection._call_queue.get(
                    self.connection._get_thread_id(), [])
                if api_call in call_queue:
                    call_queue.remove(api_call)
                e = RestException(original_error=e,
                                  stack=traceback.format_exc())
                log.error('ApiCall Exception: %s' % e, exc_info=True)
                raise e
            return self.connection._post_process_call(
                api_call, data, method_return_types)

        method_decorator.rest_method = True
        return method_decorator