Example #1
0
    def decorate(fn):
        if not inspect.isfunction(fn):
            raise Exception("not a decoratable function")
        spec = inspect_getfullargspec(fn)
        names = tuple(spec[0]) + spec[1:3] + (fn.func_name, )
        targ_name, fn_name = _unique_symbols(names, 'target', 'fn')

        metadata = dict(target=targ_name, fn=fn_name)
        metadata.update(format_argspec_plus(spec, grouped=False))

        code = 'lambda %(args)s: %(target)s(%(fn)s, %(apply_kw)s)' % (metadata)
        decorated = eval(code, {targ_name: target, fn_name: fn})
        decorated.func_defaults = getattr(fn, 'im_func', fn).func_defaults
        return update_wrapper(decorated, fn)
    def decorate(fn):
        if not inspect.isfunction(fn):
            raise Exception("not a decoratable function")
        spec = inspect_getfullargspec(fn)
        names = tuple(spec[0]) + spec[1:3] + (fn.func_name,)
        targ_name, fn_name = _unique_symbols(names, "target", "fn")

        metadata = dict(target=targ_name, fn=fn_name)
        metadata.update(format_argspec_plus(spec, grouped=False))

        code = "lambda %(args)s: %(target)s(%(fn)s, %(apply_kw)s)" % (metadata)
        decorated = eval(code, {targ_name: target, fn_name: fn})
        decorated.func_defaults = getattr(fn, "im_func", fn).func_defaults
        return update_wrapper(decorated, fn)
Example #3
0
def format_argspec_plus(fn, grouped=True):
    """Returns a dictionary of formatted, introspected function arguments.

    A enhanced variant of inspect.formatargspec to support code generation.

    fn
       An inspectable callable or tuple of inspect getargspec() results.
    grouped
      Defaults to True; include (parens, around, argument) lists

    Returns:

    args
      Full inspect.formatargspec for fn
    self_arg
      The name of the first positional argument, varargs[0], or None
      if the function defines no positional arguments.
    apply_pos
      args, re-written in calling rather than receiving syntax.  Arguments are
      passed positionally.
    apply_kw
      Like apply_pos, except keyword-ish args are passed as keywords.

    Example::

      >>> format_argspec_plus(lambda self, a, b, c=3, **d: 123)
      {'args': '(self, a, b, c=3, **d)',
       'self_arg': 'self',
       'apply_kw': '(self, a, b, c=c, **d)',
       'apply_pos': '(self, a, b, c, **d)'}

    """
    if callable(fn):
        spec = inspect_getfullargspec(fn)
    else:
        # we accept an existing argspec...
        spec = fn
    args = inspect.formatargspec(*spec)
    if spec[0]:
        self_arg = spec[0][0]
    elif spec[1]:
        self_arg = '%s[0]' % spec[1]
    else:
        self_arg = None

    # Py3K
    #apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2], None, spec[4])
    #num_defaults = 0
    #if spec[3]:
    #    num_defaults += len(spec[3])
    #if spec[4]:
    #    num_defaults += len(spec[4])
    #name_args = spec[0] + spec[4]
    # Py2K
    apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2])
    num_defaults = 0
    if spec[3]:
        num_defaults += len(spec[3])
    name_args = spec[0]
    # end Py2K

    if num_defaults:
        defaulted_vals = name_args[0 - num_defaults:]
    else:
        defaulted_vals = ()

    apply_kw = inspect.formatargspec(name_args,
                                     spec[1],
                                     spec[2],
                                     defaulted_vals,
                                     formatvalue=lambda x: '=' + x)
    if grouped:
        return dict(args=args,
                    self_arg=self_arg,
                    apply_pos=apply_pos,
                    apply_kw=apply_kw)
    else:
        return dict(args=args[1:-1],
                    self_arg=self_arg,
                    apply_pos=apply_pos[1:-1],
                    apply_kw=apply_kw[1:-1])
Example #4
0
def format_argspec_plus(fn, grouped=True):
    """Returns a dictionary of formatted, introspected function arguments.

    A enhanced variant of inspect.formatargspec to support code generation.

    fn
       An inspectable callable or tuple of inspect getargspec() results.
    grouped
      Defaults to True; include (parens, around, argument) lists

    Returns:

    args
      Full inspect.formatargspec for fn
    self_arg
      The name of the first positional argument, varargs[0], or None
      if the function defines no positional arguments.
    apply_pos
      args, re-written in calling rather than receiving syntax.  Arguments are
      passed positionally.
    apply_kw
      Like apply_pos, except keyword-ish args are passed as keywords.

    Example::

      >>> format_argspec_plus(lambda self, a, b, c=3, **d: 123)
      {'args': '(self, a, b, c=3, **d)',
       'self_arg': 'self',
       'apply_kw': '(self, a, b, c=c, **d)',
       'apply_pos': '(self, a, b, c, **d)'}

    """
    if callable(fn):
        spec = inspect_getfullargspec(fn)
    else:
        # we accept an existing argspec...
        spec = fn
    args = inspect.formatargspec(*spec)
    if spec[0]:
        self_arg = spec[0][0]
    elif spec[1]:
        self_arg = '%s[0]' % spec[1]
    else:
        self_arg = None

    # Py3K
    #apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2], None, spec[4])
    #num_defaults = 0
    #if spec[3]:
    #    num_defaults += len(spec[3])
    #if spec[4]:
    #    num_defaults += len(spec[4])
    #name_args = spec[0] + spec[4]
    # Py2K
    apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2])
    num_defaults = 0
    if spec[3]:
        num_defaults += len(spec[3])
    name_args = spec[0]
    # end Py2K

    if num_defaults:
        defaulted_vals = name_args[0-num_defaults:]
    else:
        defaulted_vals = ()

    apply_kw = inspect.formatargspec(name_args, spec[1], spec[2], defaulted_vals,
                                     formatvalue=lambda x: '=' + x)
    if grouped:
        return dict(args=args, self_arg=self_arg,
                    apply_pos=apply_pos, apply_kw=apply_kw)
    else:
        return dict(args=args[1:-1], self_arg=self_arg,
                    apply_pos=apply_pos[1:-1], apply_kw=apply_kw[1:-1])