Exemple #1
0
    def __call__(self, f):
        argspec = misc.getargspec(f)
        self.arg_names = argspec[0]
        self.have_varargs = (argspec[1] is not None) and not self.add_varargs

        assert ((len(self.constraints) == len(self.arg_names)
                    and not self.have_varargs)
             or (len(self.constraints) == len(self.arg_names) + 1
                    and self.have_varargs))

        if self.add_varargs:
            # add varargs to the signature and use decorator.FunctionMaker
            # directly to create the decorated function
            orig_signature = inspect.getargspec(f)
            assert orig_signature.varargs is None
            signature = orig_signature._replace(varargs='args')
            evaldict = self.wrapper.__globals__.copy()
            evaldict['_call_'] = self.wrapper
            evaldict['_func_'] = f
            return decorator.FunctionMaker.create(
                '%s%s' % (f.__name__, inspect.formatargspec(*signature)),
                'return _call_(_func_, %(shortsignature)s)',
                evaldict, undecorated=f, __wrapped__=f, doc=f.__doc__)
        else:
            return decorator.decorator(self.wrapper, f)
Exemple #2
0
    def __call__(self, f):
        argspec = misc.getargspec(f)
        self.arg_names = argspec[0]
        self.have_varargs = (argspec[1] is not None) and not self.add_varargs

        assert ((len(self.constraints) == len(self.arg_names)
                 and not self.have_varargs)
                or (len(self.constraints) == len(self.arg_names) + 1
                    and self.have_varargs))

        if self.add_varargs:
            # add varargs to the signature and use decorator.FunctionMaker
            # directly to create the decorated function
            orig_signature = inspect.getargspec(f)
            assert orig_signature.varargs is None
            signature = orig_signature._replace(varargs='args')
            evaldict = self.wrapper.__globals__.copy()
            evaldict['_call_'] = self.wrapper
            evaldict['_func_'] = f
            return decorator.FunctionMaker.create(
                '%s%s' % (f.__name__, inspect.formatargspec(*signature)),
                'return _call_(_func_, %(shortsignature)s)',
                evaldict,
                undecorated=f,
                __wrapped__=f,
                doc=f.__doc__)
        else:
            return decorator.decorator(self.wrapper, f)
Exemple #3
0
def call(args, kwargs, funcs, name=None):
    """
    Search funcs for a function with parameters such that args and kwargs
    can be applied, and call the first suitable function that is found.
    """
    for f in funcs:
        n = len(args)

        # get argument names and the number of default arguments of f
        argspec = misc.getargspec(f)
        names = argspec[0]
        varargs = argspec[1]
        ndef = len(argspec[3]) if argspec[3] else 0

        # names of the default arguments not overridden by positional arguments
        npos = max(len(names) - ndef, n)
        defargs = names[npos:]

        # check if the number of positional arguments fits, and if the
        # remaining parameters can be filled with keyword and default
        # arguments.
        # alternatively, a suitable function with varargs is also accepted.
        if ((n <= len(names) and set(kwargs) | set(defargs) == set(names[n:]))
                or (n >= len(names) and varargs is not None)):
            # call f with all original arguments
            return f(*args, **kwargs)

    # no overload found, generate a comprehensible error message
    if name is None:
        name = inspect.stack()[1][3]

    # format arg spec for each candidate
    formatargspec = lambda f: inspect.formatargspec(*misc.getargspec(f))
    candidates = ('    %s%s' % (name, formatargspec(f)) for f in funcs)

    # formatargspec() doesn't seem to care that the first argument mixes
    # asterisks and argument names
    argx = ['*'] * len(args)
    kwargx = ['*'] * len(kwargs)
    formatvalue = lambda v: '=%s' % v
    args_used = inspect.formatargspec(argx + list(kwargs.keys()),
                                      defaults=kwargx,
                                      formatvalue=formatvalue)

    message = ("no suitable overload found for %s%s, candidates are:\n%s" %
               (name, args_used, '\n'.join(candidates)))
    raise TypeError(message)
Exemple #4
0
def call(args, kwargs, funcs, name=None):
    """
    Search funcs for a function with parameters such that args and kwargs
    can be applied, and call the first suitable function that is found.
    """
    for f in funcs:
        n = len(args)

        # get argument names and the number of default arguments of f
        argspec = misc.getargspec(f)
        names = argspec[0]
        varargs = argspec[1]
        ndef = len(argspec[3]) if argspec[3] else 0

        # names of the default arguments not overridden by positional arguments
        npos = max(len(names) - ndef, n)
        defargs = names[npos:]

        # check if the number of positional arguments fits, and if the
        # remaining parameters can be filled with keyword and default
        # arguments.
        # alternatively, a suitable function with varargs is also accepted.
        if ((n <= len(names) and set(kwargs) | set(defargs) == set(names[n:]))
                or (n >= len(names) and varargs is not None)):
            # call f with all original arguments
            return f(*args, **kwargs)

    # no overload found, generate a comprehensible error message
    if name is None:
        name = inspect.stack()[1][3]

    # format arg spec for each candidate
    formatargspec = lambda f: inspect.formatargspec(*misc.getargspec(f))
    candidates = ('    %s%s' % (name, formatargspec(f)) for f in funcs)

    # formatargspec() doesn't seem to care that the first argument mixes
    # asterisks and argument names
    argx = ['*'] * len(args)
    kwargx = ['*'] * len(kwargs)
    formatvalue = lambda v: '=%s' % v
    args_used = inspect.formatargspec(argx + list(kwargs.keys()),
                                      defaults=kwargx, formatvalue=formatvalue)

    message = ("no suitable overload found for %s%s, candidates are:\n%s" %
                    (name, args_used, '\n'.join(candidates)))
    raise TypeError(message)
Exemple #5
0
def unit_to_string(unit):
    # can't do anything for units that didn't go through @store (or @accept)
    assert hasattr(unit, '_name')

    argnames = misc.getargspec(unit._function)[0]

    args = [
        misc.bytestring(a) if isinstance(a, bytearray) else a
        for a in unit._args
    ]

    # (ab)use inspect module to format the arguments used
    formatted = inspect.formatargspec(args=argnames, defaults=args)
    return unit._name + formatted
Exemple #6
0
def unit_to_string(unit):
    # can't do anything for units that didn't go through @store (or @accept)
    assert hasattr(unit, '_name')

    argnames = misc.getargspec(unit._function)[0]

    args = [
        misc.bytestring(a) if isinstance(a, bytearray) else a
        for a in unit._args
    ]

    # (ab)use inspect module to format the arguments used
    formatted = inspect.formatargspec(args=argnames, defaults=args)
    return unit._name + formatted