def transform_varargs(annotator, v_func, v_shape, *data_v): callspec = CallSpec.fromshape(v_shape.value, list(data_v)) v_vararg = callspec.w_stararg if callspec.w_stararg: s_vararg = annotator.annotation(callspec.w_stararg) if not isinstance(s_vararg, SomeTuple): raise AnnotatorError( "Calls like f(..., *arg) require 'arg' to be a tuple") n_items = len(s_vararg.items) ops = [op.getitem(v_vararg, const(i)) for i in range(n_items)] new_args = callspec.arguments_w + [hlop.result for hlop in ops] if callspec.keywords: newspec = CallSpec(new_args, callspec.keywords) shape, data_v = newspec.flatten() call_op = op.call_args(v_func, const(shape), *data_v) else: call_op = op.simple_call(v_func, *new_args) ops.append(call_op) return ops
def call_function(self, oparg, w_star=None, w_starstar=None): if w_starstar is not None: raise FlowingError("Dict-unpacking is not RPython") n_arguments = oparg & 0xff n_keywords = (oparg >> 8) & 0xff keywords = {} for _ in range(n_keywords): w_value = self.popvalue() w_key = self.popvalue() key = w_key.value keywords[key] = w_value arguments = self.popvalues(n_arguments) args = CallSpec(arguments, keywords, w_star) w_function = self.popvalue() if args.keywords or isinstance(args.w_stararg, Variable): shape, args_w = args.flatten() hlop = op.call_args(w_function, Constant(shape), *args_w) else: hlop = op.simple_call(w_function, *args.as_list()) self.pushvalue(hlop.eval(self))
def test_flatten_CallSpec(): args = CallSpec([1, 2, 3]) assert args.flatten() == ((3, (), False), [1, 2, 3]) args = CallSpec([1]) assert args.flatten() == ((1, (), False), [1]) args = CallSpec([1, 2, 3, 4, 5]) assert args.flatten() == ((5, (), False), [1, 2, 3, 4, 5]) args = CallSpec([1], {'c': 3, 'b': 2}) assert args.flatten() == ((1, ('b', 'c'), False), [1, 2, 3]) args = CallSpec([1], {'c': 5}) assert args.flatten() == ((1, ('c', ), False), [1, 5]) args = CallSpec([1], {'c': 5, 'd': 7}) assert args.flatten() == ((1, ('c', 'd'), False), [1, 5, 7]) args = CallSpec([1, 2, 3, 4, 5], {'e': 5, 'd': 7}) assert args.flatten() == ((5, ('d', 'e'), False), [1, 2, 3, 4, 5, 7, 5])