def visit_FunctionDef(self, node):
        writer.write('def %s(args, kwargs):' % node.name)
        writer.push()

        # new pythonjs' python function arguments handling
        # create the structure representing the functions arguments
        # first create the defaultkwargs JSObject
        writer.write('var(signature, arguments)')
        L = len(node.args.defaults)
        kwargsdefault = map(lambda x: keyword(self.visit(x[0]), x[1]), zip(node.args.args[-L:], node.args.defaults))
        kwargsdefault = Call(
            Name('JSObject', None),
            [],
            kwargsdefault,
            None,
            None
        )
        args = Call(
            Name('JSArray', None),
            map(lambda x: Str(x.id), node.args.args),
            [],
            None,
            None
        )
        keywords = list([
            keyword(Name('kwargs', None), kwargsdefault),
            keyword(Name('args', None), args),
        ])
        if node.args.vararg:
            keywords.append(keyword(Name('vararg', None), Str(node.args.vararg)))
        if node.args.kwarg:
            keywords.append(keyword(Name('varkwarg', None), Str(node.args.kwarg)))

        prebody = list()

        # create a JS Object to store the value of each parameter
        signature = ', '.join(map(lambda x: '%s=%s' % (self.visit(x.arg), self.visit(x.value)), keywords))
        writer.write('signature = JSObject(%s)' % signature)
        writer.write('arguments = get_arguments(signature, args, kwargs)')
        # # then for each argument assign its value
        for arg in node.args.args:
            writer.write("""JS("var %s = arguments['%s']")""" % (arg.id, arg.id))
        if node.args.vararg:
            writer.write("""JS("var %s arguments['%s']")""" % (node.args.vararg, node.args.vararg))
            # turn it into a list
            expr = '%s = get_attribute(list, "__call__")(create_array(%s), {});'
            expr = expr % (node.args.vararg, node.args.vararg)
            writer.write(expr)
        if node.args.kwarg:
            writer.write("""JS('var %s = arguments["%s"]')""" % (node.args.kwarg, node.args.kwarg))
            expr = '%s = get_attribute(dict, "__call__")(create_array(%s), {});'
            expr = expr % (node.args.kwarg, node.args.kwarg)
            writer.write(expr)

        map(self.visit, node.body)
        writer.pull()

        # apply decorators
        for decorator in reversed(node.decorator_list):
            writer.write('%s = %s(create_array(%s))' % (node.name, self.visit(decorator), node.name))
Esempio n. 2
0
    def visit_Compare (self, node):
        self.generic_visit (node)
        ans= node

        # ls () < "bar.txt" > "foo.txt"
        # Compare(left=Call(func=Name(id='ls', ctx=Load()), args=[], keywords=[],
        #                        starargs=None, kwargs=None),
        #         ops=[Lt(), Gt()],
        #         comparators=[Str(s='bar.txt'), Str(s='foo.txt')]))

        if is_executable (node.left):
            # yes, they're reversed, but it makes more sense to me like this
            for comp, op in zip (node.ops, node.comparators):
                if type (comp)==Gt:
                    # > means _out
                    update_keyword (node.left, keyword (arg='_out', value=op))
                    ans= node.left
                elif type (comp)==GtE:
                    # >= means _out+_err
                    update_keyword (node.left, keyword (arg='_out', value=op))
                    update_keyword (node.left, keyword (arg='_err_to_out', value=op))
                    ans= node.left
                elif type (comp)==Lt:
                    # < means _in
                    update_keyword (node.left, keyword (arg='_in', value=op))
                    ans= node.left

        return ans
Esempio n. 3
0
 def test_keywords_wildcard(self):
     apf = ASTPatternFinder(prepare_pattern("f(e=4, ??=??)"))
     it = apf.scan_ast(self.ast)
     assert_ast_like(next(it), ast.Call(keywords=[ast.keyword(arg='d'),
                                                  ast.keyword(arg='e'),])
                     )
     self.assert_no_more(it)
 def test_Call(self):
     name = ast.Name('spam', ast.Load())
     args = ([ast.Num(42)], '42'), ([], None)
     keywords = ([ast.keyword('X', ast.Num(42))], 'X=42'), ([], None)
     starargs = (ast.Name('args', ast.Load()), '*args'), (None, None)
     kwargs = (ast.Name('kwargs', ast.Load()), '**kwargs'), (None, None)
     for arg in args:
         for keyword in keywords:
             for stararg in starargs:
                 for kwarg in kwargs:
                     node = ast.Call(name, arg[0], keyword[0], stararg[0],
                                     kwarg[0])
                     expect = 'spam({})'.format(','.join(x for x in
                                 (arg[1], keyword[1], stararg[1], kwarg[1])
                                 if x))
                     self.verify(node, expect)
     self.verify(ast.Call(name, [ast.Num(2), ast.Num(3)], [], None, None),
                 'spam(2,3)')
     self.verify(ast.Call(name, [],
                     [ast.keyword('X', ast.Num(0)),
                         ast.keyword('Y', ast.Num(1))],
                     None, None),
                 'spam(X=0,Y=1)')
     # A single genexp doesn't need parentheses.
     genexp = self.seq_comp_test(ast.GeneratorExp, '()')
     self.verify(ast.Call(name, [genexp], [], None, None),
                 'spam(w for x in y if 2 for a in b)')
     self.verify(ast.Call(name, [genexp, genexp], [], None, None),
                 'spam((w for x in y if 2 for a in b),'
                 '(w for x in y if 2 for a in b))')
Esempio n. 5
0
  def visit_Call(self, node, parent):
    if node in self.seen:
      return node
    self.seen.add(node)

    callName = dict(ast.iter_fields(dict(ast.iter_fields(node))['func'])).get('id', None)
    callType = dict(ast.iter_fields(dict(ast.iter_fields(node))['func'])).get('attr',None)
    #print ast.dump(dict(ast.iter_fields(node))['func']), callType, node.lineno, node.col_offset
    #print callName, self.localFuncs
    if callName in self.localFuncs:
      #print ast.dump(node)
      #print callName, node.lineno, node.col_offset
      dict(ast.iter_fields(node))['keywords'].append(ast.keyword(arg=self.calleeInfo, value=ast.Str(s=str(node.lineno) + "-" + str(node.col_offset))))
      
    if callType in erps.keys() or callType == "stocPrim":
      if callType not in self.primsNumArgs:
        self.primsNumArgs[callType] = len(inspect.getargspec(globals()[callType]).args)

      namedArgs = map(lambda x: dict(ast.iter_fields(x))['arg'], dict(ast.iter_fields(node))['keywords'])
      numArgs = len(namedArgs) + len(dict(ast.iter_fields(node))['args']) 
      #print callType, node.lineno, node.col_offset
      #print ast.dump(parent)
      if not ('name' in namedArgs or numArgs == self.primsNumArgs[callType]): #check if name already supplied
        dict(ast.iter_fields(node))['keywords'].append(ast.keyword(arg='name', value=ast.BinOp(left=ast.BinOp(left=ast.Call(func=ast.Name(id='str', ctx=ast.Load()), args=[ast.Name(id=self.funcStack, ctx=ast.Load())], keywords=[], starargs=None, kwargs=None), op=ast.Add(), right=ast.Call(func=ast.Name(id='str', ctx=ast.Load()), args=[ast.Name(id=self.locStack, ctx=ast.Load())], keywords=[], starargs=None, kwargs=None)), op=ast.Add(), right=ast.BinOp(left=ast.Str(s=str(node.lineno) + "-" + str(node.col_offset)), op=ast.Add(), right=ast.Call(func=ast.Name(id='str', ctx=ast.Load()), args=[ast.Name(id=self.loopStack, ctx=ast.Load())], keywords=[], starargs=None, kwargs=None)))))

    
    ast.fix_missing_locations(node)
    #print map(ast.dump, dict(ast.iter_fields(node))['keywords'])
    self.generic_visit(node)
    return node
    def visit_BinOp(self, node):
        if node.op.__class__ in self.operators:
            sympy_class = self.operators[node.op.__class__]
            right = self.visit(node.right)

            if isinstance(node.op, ast.Sub):
                right = ast.UnaryOp(op=ast.USub(), operand=right)
            elif isinstance(node.op, ast.Div):
                right = ast.Call(
                    func=ast.Name(id='Pow', ctx=ast.Load()),
                    args=[right, ast.UnaryOp(op=ast.USub(), operand=ast.Num(1))],
                    keywords=[ast.keyword(arg='evaluate', value=ast.Name(id='False', ctx=ast.Load()))],
                    starargs=None,
                    kwargs=None
                )

            new_node = ast.Call(
                func=ast.Name(id=sympy_class, ctx=ast.Load()),
                args=[self.visit(node.left), right],
                keywords=[ast.keyword(arg='evaluate', value=ast.Name(id='False', ctx=ast.Load()))],
                starargs=None,
                kwargs=None
            )

            if sympy_class in ('Add', 'Mul'):
                # Denest Add or Mul as appropriate
                new_node.args = self.flatten(new_node.args, sympy_class)

            return new_node
        return node
Esempio n. 7
0
    def _compile_directive_call_assets(self, el, options):
        """ This special 't-call' tag can be used in order to aggregate/minify javascript and css assets"""
        if len(el):
            raise SyntaxError("t-call-assets cannot contain children nodes")

        # self._get_asset(xmlid, options, css=css, js=js, debug=values.get('debug'), async=async, values=values)
        return [
            self._append(ast.Call(
                func=ast.Attribute(
                    value=ast.Name(id='self', ctx=ast.Load()),
                    attr='_get_asset',
                    ctx=ast.Load()
                ),
                args=[
                    ast.Str(el.get('t-call-assets')),
                    ast.Name(id='options', ctx=ast.Load()),
                ],
                keywords=[
                    ast.keyword('css', self._get_attr_bool(el.get('t-css', True))),
                    ast.keyword('js', self._get_attr_bool(el.get('t-js', True))),
                    ast.keyword('debug', ast.Call(
                        func=ast.Attribute(
                            value=ast.Name(id='values', ctx=ast.Load()),
                            attr='get',
                            ctx=ast.Load()
                        ),
                        args=[ast.Str('debug')],
                        keywords=[], starargs=None, kwargs=None
                    )),
                    ast.keyword('async', self._get_attr_bool(el.get('async', False))),
                    ast.keyword('values', ast.Name(id='values', ctx=ast.Load())),
                ],
                starargs=None, kwargs=None
            ))
        ]
Esempio n. 8
0
    def visit_Compare (self, node):
        self.generic_visit (node)
        ans= node

        # ls () < "bar.txt" > "foo.txt"
        # Compare(left=Call(func=Name(id='ls', ctx=Load()), args=[], keywords=[],
        #                        starargs=None, kwargs=None),
        #         ops=[Lt(), Gt()],
        #         comparators=[Str(s='bar.txt'), Str(s='foo.txt')]))

        if self.is_executable (node.left):
            # yes, they're reversed, but it makes more sense to me like this
            for comp, op in zip (node.ops, node.comparators):
                if type (comp)==Gt:
                    # > means _out
                    node.left.keywords.append (keyword (arg='_out', value=op))
                    ans= node.left
                elif type (comp)==Lt:
                    # < means _in

                    # now, _in works differently
                    # a string is written directly to the stdin,
                    # instead of creating a file() with that name
                    # so, we do it ourseleves.
                    if type (op)==Str:
                        op= Call (func=Name (id='open', ctx=Load ()), args=[op],
                                  keywords=[], starargs=None, kwargs=None)

                    node.left.keywords.append (keyword (arg='_in', value=op))
                    ast.fix_missing_locations (node.left)
                    ans= node.left

        return ans
Esempio n. 9
0
 def visit_Call(self, node):
     if isinstance(node.func, ast.Name) and isinstance(node.func.ctx, ast.Load):
         if node.func.id in map(lambda x: x.value, list(TradingCommands)):
             parser = LocationPatcher(node)
             node.keywords.append(parser.visit(ast.keyword(arg="lineno", value=ast.Num(n=node.lineno))))
             node.keywords.append(parser.visit(ast.keyword(arg="col_offset", value=ast.Num(n=node.col_offset))))
     return node
Esempio n. 10
0
 def make_argparse_arguments(self):
     for arg, name, help, action in self.macro_handler.args:
         expr = ast.parse('parser.add_argument()').body[0]
         expr.value.args = [ast.Str(arg)]
         expr.value.keywords = [
             ast.keyword('dest', ast.Str(name)),
             ast.keyword('action', ast.Str(action)),
             ast.keyword('help', ast.Str(help)),
         ]
         yield expr
Esempio n. 11
0
def nameAndArgsToKeyword(name, args):
    if name in groupbySet:
        arg = 'groupby'
        keyword = ast.keyword(arg=arg, value = ast.Dict(keys=args, values=args))
    elif name in aggregationSet:
        arg = 'aggregate'
        keyword = ast.keyword(arg=arg, value = ast.Dict(keys=[ast.Str(name),], values=[ast.List(elts=args)]))
    else:
        raise NotImplementedError
    return keyword
Esempio n. 12
0
 def test_call(self):
     func = ast.Name("x", ast.Load())
     args = [ast.Name("y", ast.Load())]
     keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
     call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
     self.expr(call, "must have Load context")
     call = ast.Call(func, [None], keywords)
     self.expr(call, "None disallowed")
     bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
     call = ast.Call(func, args, bad_keywords)
     self.expr(call, "must have Load context")
Esempio n. 13
0
 def test_wildcard_call_mixed_args(self):
     pat = prepare_pattern("f(1, ??, a=2, **{'b':3})")
     assert isinstance(pat.args, listmiddle)
     assert_ast_like(pat.args.front[0], ast.Num(n=1))
     assert not hasattr(pat, 'starargs')
     assert isinstance(pat.keywords, types.FunctionType)
     kwargs_dict = ast.Dict(keys=[ast.Str(s='b')], values=[ast.Num(n=3)])
     if sys.version_info < (3, 5):
         assert_ast_like(pat.kwargs, kwargs_dict)
     else:
         pat.keywords([ast.keyword(arg=None, value=kwargs_dict),
                       ast.keyword(arg='a', value=ast.Num(n=2))], [])
Esempio n. 14
0
 def create_super_call(self, node):
     super_call = utils.create_ast('super().{}()'.format(node.name)).body[0]
     for arg in node.args.args[1:-len(node.args.defaults) or None]:
         super_call.value.args.append(ast.Name(id=arg.arg, ctx=ast.Load()))
     for arg, default in zip(node.args.args[-len(node.args.defaults):], node.args.defaults):
         super_call.value.keywords.append(ast.keyword(arg=arg.arg, value=default))
     for arg, default in zip(node.args.kwonlyargs, node.args.kw_defaults):
         super_call.value.keywords.append(ast.keyword(arg=arg.arg, value=default))
     if node.args.vararg:
         super_call.value.starargs = ast.Name(id=node.args.vararg, ctx=ast.Load())
     if node.args.kwarg:
         super_call.value.kwargs = ast.Name(id=node.args.kwarg, ctx=ast.Load())
     return super_call
Esempio n. 15
0
 def test_pos_final_wildcard(self):
     apf = ASTPatternFinder(prepare_pattern("f(1, ??)"))
     it = apf.scan_ast(self.ast)
     assert_ast_like(next(it), ast.Call(args=[ast.Num(n=1)]))
     assert_ast_like(next(it), ast.Call(args=[ast.Num(n=1), ast.Num(n=2)]))
     assert_ast_like(next(it), ast.Call(starargs=ast.Name(id='c')))
     assert_ast_like(next(it), ast.Call(args=[ast.Num(n=1)],
                                      keywords=[ast.keyword(arg='d'),
                                                ast.keyword(arg='e'),
                                               ])
                    )
     assert_ast_like(next(it), ast.Call(kwargs=ast.Name(id='k')))
     self.assert_no_more(it)
Esempio n. 16
0
    def visit_BinOp (self, node):
        self.generic_visit (node)

        # BinOp( left=Call(...), op=BitOr(), right=Call(...))
        if type (node.op)==BitOr:
            # pipe
            # BinOp (left, BitOr, right) -> right (left, ...)

            # check the left and right; if they're calls to CommandWrapper._create
            # then do the magic

            both= True
            for child in (node.left, node.right):
                both= both and self.is_executable (child)

            if both:
                # right (left, ...)
                # I can't believe it's this easy
                node.left.keywords.append (keyword (arg='_out',
                                                    value=Name (id='Capture', ctx=Load ())))
                ast.fix_missing_locations (node.left)
                node.right.args.insert (0, node.left)
                node= node.right

                # Call(func=Call(func=Attribute(value=Name(id='CommandWrapper', ctx=Load()),
                #                               attr='_create', ctx=Load()),
                #                args=[Str(s='grep')], keywords=[], starargs=None, kwargs=None),
                #      args=[Call(func=Call(func=Attribute(value=Name(id='CommandWrapper', ctx=Load()),
                #                                          attr='_create', ctx=Load()),
                #                      args=[Str(s='ls')], keywords=[], starargs=None, kwargs=None),
                #                 args=[], keywords=[keyword(arg='_out',
                #                                            value=Name(id='Capture', ctx=Load()))],
                #                 starargs=None, kwargs=None),
                #            Str(s='foo')],
                #      keywords=[], starargs=None, kwargs=None)

        elif type (node.op)==RShift:
            # BinOp(left=Call(func=Name(id='ls', ctx=Load()), args=[], keywords=[], starargs=None, kwargs=None),
            #       op=RShift(),
            #       right=Str(s='foo.txt'))
            if self.is_executable (node.left):
                node.left.keywords.append (keyword (arg='_out',
                                                    value=Call (func=Name (id='open', ctx=Load ()),
                                                                args=[node.right, Str (s='ab')], keywords=[], starargs=None, kwargs=None)))
                ast.fix_missing_locations (node.left)
                node= node.left

        return node
Esempio n. 17
0
def ClassDef(*, name, bases, keywords, starargs, kwargs, body, decorator_list, lineno=None, col_offset=None):
    if flags.PY_VERSION == 2:
        # Ignore keywords and starargs, they shouldnt be there in the first place if Py2
        return ast.ClassDef(name=name, bases=bases, body=body, 
                            decorator_list=decorator_list, lineno=lineno, col_offset=col_offset)
    elif flags.PY_VERSION == 3:
        if flags.PY3_VERSION >= 5:
            if starargs is not None:
                bases += [ast.Starred(starargs, ast.Load())]
            if kwargs is not None:
                keywords += [ast.keyword(arg=None, value=kwargs)]
            if lineno is not None and col_offset is not None:
                return ast.ClassDef(name=name, bases=bases, keywords=keywords, body=body,
                                    decorator_list=decorator_list, lineno=lineno, col_offset=col_offset)
            else:
                return ast.ClassDef(name=name, bases=bases, keywords=keywords, body=body,
                                    decorator_list=decorator_list)
        else: 
            if lineno is not None and col_offset is not None:
                return ast.ClassDef(name=name, bases=bases, keywords=keywords, 
                                    starargs=starargs, kwargs=kwargs, body=body,
                                    decorator_list=decorator_list, lineno=lineno, col_offset=col_offset)
            else:
                return ast.ClassDef(name=name, bases=bases, keywords=keywords, 
                                    starargs=starargs, kwargs=kwargs, body=body,
                                    decorator_list=decorator_list)
Esempio n. 18
0
 def test_classdef(self):
     def cls(bases=None, keywords=None, starargs=None, kwargs=None,
             body=None, decorator_list=None):
         if bases is None:
             bases = []
         if keywords is None:
             keywords = []
         if body is None:
             body = [ast.Pass()]
         if decorator_list is None:
             decorator_list = []
         return ast.ClassDef("myclass", bases, keywords, starargs,
                             kwargs, body, decorator_list)
     self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
               "must have Load context")
     self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
               "must have Load context")
     self.stmt(cls(starargs=ast.Name("x", ast.Store())),
               "must have Load context")
     self.stmt(cls(kwargs=ast.Name("x", ast.Store())),
               "must have Load context")
     self.stmt(cls(body=[]), "empty body on ClassDef")
     self.stmt(cls(body=[None]), "None disallowed")
     self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
               "must have Load context")
Esempio n. 19
0
def get_call_ast(func_name, args=None, kwargs=None, return_type=None):
    """ Return an AST representing the call to a function with the name
    func_name, passing it the arguments args (given as a list) and the
    keyword arguments kwargs (given as a dictionary).
    func_name -- either the name of a callable as a string, or an AST
        representing a callable expression
    return_type -- if this is not None, return a TypedCall object with this
        return type instead """
    if args is None:
        args = []
    # convert keyword argument dict to a list of (key, value) pairs
    keywords = []
    if kwargs is not None:
        for (key, value) in kwargs.iteritems():
            keywords.append(ast.keyword(arg=key, value=value))
    # get or generate the AST representing the callable
    if isinstance(func_name, ast.AST):
        func_ast = func_name
    else:
        func_ast = ast.Name(id=func_name, ctx=ast.Load)
    # if no return type is given, return a simple Call AST
    if return_type is None:
        return ast.Call(func=func_ast, args=args, keywords=keywords,
                        starargs=None, kwargs=None)
    # if a return type is given, return a TypedCall AST
    else:
        return TypedCall(func=func_ast, args=args, keywords=keywords,
                         return_type=return_type)
Esempio n. 20
0
 def visit_Call(self, call):
     new_func, func_expl = self.visit(call.func)
     arg_expls = []
     new_args = []
     new_kwargs = []
     new_star = new_kwarg = None
     for arg in call.args:
         res, expl = self.visit(arg)
         new_args.append(res)
         arg_expls.append(expl)
     for keyword in call.keywords:
         res, expl = self.visit(keyword.value)
         new_kwargs.append(ast.keyword(keyword.arg, res))
         arg_expls.append(keyword.arg + "=" + expl)
     if call.starargs:
         new_star, expl = self.visit(call.starargs)
         arg_expls.append("*" + expl)
     if call.kwargs:
         new_kwarg, expl = self.visit(call.kwargs)
         arg_expls.append("**" + expl)
     expl = "%s(%s)" % (func_expl, ', '.join(arg_expls))
     new_call = ast.Call(new_func, new_args, new_kwargs, new_star, new_kwarg)
     res = self.assign(new_call)
     res_expl = self.explanation_param(self.display(res))
     outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl)
     return res, outer_expl
Esempio n. 21
0
    def visit_Call_35(self, call):
        """
        visit `ast.Call` nodes on Python3.5 and after
        """
        new_func, func_expl = self.visit(call.func)
        arg_expls = []
        new_args = []
        new_kwargs = []
        for arg in call.args:
            res, expl = self.visit(arg)
            arg_expls.append(expl)
            new_args.append(res)
        for keyword in call.keywords:
            res, expl = self.visit(keyword.value)
            new_kwargs.append(ast.keyword(keyword.arg, res))
            if keyword.arg:
                arg_expls.append(keyword.arg + "=" + expl)
            else: ## **args have `arg` keywords with an .arg of None
                arg_expls.append("**" + expl)

        expl = "%s(%s)" % (func_expl, ', '.join(arg_expls))
        new_call = ast.Call(new_func, new_args, new_kwargs)
        res = self.assign(new_call)
        res_expl = self.explanation_param(self.display(res))
        outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl)
        return res, outer_expl
Esempio n. 22
0
def do_for(parser, token):
    '''
    {% for a, b, c in iterable %}

    {% endfor %}

    We create the structure:

    for a, b, c in iterable:
        with helpers['forwrapper'](context, a=a, b=b, c=c):
            ...
    '''
    code = ast.parse('for %s: pass' % token, mode='exec')

    loop = code.body[0]
    loop.iter = wrap_name_in_context(loop.iter)
    body, _ = parser.parse_nodes_until('endfor')

    if isinstance(loop.target, ast.Tuple):
        targets = [elt.id for elt in loop.target.elts]
    else:
        targets = [loop.target.id]

    kwargs = [
        ast.keyword(arg=elt, value=ast.Name(id=elt, ctx=ast.Load()))
        for elt in targets
    ]

    loop.body = [_create_with_scope(body, kwargs)]

    return loop
Esempio n. 23
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code
        sig = acode[1].code
        mac_name = sig[0].code.full_name
        param_names = [p.code.full_name for p in sig[1:]]
        body = [s.code for s in acode[2:]]


        params_code = ast.List(elts=[ast.Str(s) for s in param_names],
                               ctx=ast.Load())

        # rcode_code =

        # __aky__.Macro( ... )
        mac_code = ast.Call(func=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                               attr="Macro", ctx=ast.Load()),
                            args=[],
                            keywords=[ast.keyword(arg="specs",
                                                  value=ast.Tuple(elts=[params_code,
                                                                        rcode_code],
                                                                  ctx=ast.Load()))])

        target_code = ast.Subscript(value=ast.Name(id="__macros__", ctx=ast.Load()),
                                    slice=ast.Index(ast.Str(mac_name)),
                                    ctx=ast.Store())

        #
        assign_code = ast.Assign(targets=[target_code],
                                       value=mac_code)


        return assign_code
Esempio n. 24
0
 def visit_Call(self, node):
     if hasattr(node.func, 'id') and node.func.id in ('JS', 'toString', 'JSObject', 'JSArray', 'var'):
         return self.generic_visit(node)
     return Call(
         Call(
             Name('get_attribute', None),
             [self.visit(node.func), Str('__call__')],
             None,
             None,
             None,
         ),
         [
             Call(
                 Name('JSArray', None),
                 map(self.visit, node.args),
                 None,
                 None,
                 None
             ),
             Call(
                 Name('JSObject', None),
                 None,
                 map(lambda x: keyword(Name(x.arg, None), self.visit(x.value)), node.keywords),
                 None,
                 None
             ),
         ],
         None,
         None,
         None,
     )
Esempio n. 25
0
def peval_call(state, ctx, func, args=[], keywords=[]):

    assert all(type(arg) != ast.Starred for arg in args)
    assert all(kw.arg is not None for kw in keywords)

    keyword_expressions = [kw.value for kw in keywords]

    state, results = map_peval_expression(
        state, dict(func=func, args=args, keywords=keyword_expressions), ctx)

    if all_known_values_or_none(results):
        values = map_get_value(results)
        kwds = {kw.arg: value for kw, value in zip(keywords, values['keywords'])}
        success, value = try_eval_call(
            values['func'], args=values['args'], keywords=kwds)
        if success:
            return state, KnownValue(value=value)

    state, nodes = map_reify(state, results)

    # restoring the keyword list
    nodes['keywords'] = [
        ast.keyword(arg=kw.arg, value=expr)
        for kw, expr in zip(keywords, nodes['keywords'])]

    return state, ast.Call(**nodes)
Esempio n. 26
0
    def visit_argument(self, values, ctx):
        """argument: test [comp_for] | test '=' test"""

        if len(values) == 1:
            node = self.visit(values[0], ctx)

        elif len(values) == 2:
            test = self.visit(values[0], ctx)
            comp_for = self.visit(values[1], ctx)

            # TODO
            node = ast.GeneratorExp()
            node.elt = test
            node.generators = [comp_for]

        elif len(values) == 3:
            node = ast.keyword()
            
            arg = self.visit(values[0], ctx)
            node.arg = arg.id

            node.value = self.visit(values[2], ctx)

        else:
            raise ValueError

        return node
Esempio n. 27
0
 def visitCall(self, n, *args):
     return ast_trans.Call(func=self.dispatch(n.func, *args),
                           args=self.reduce(n.args, *args),
                           keywords=[ast.keyword(arg=k.arg, value=self.dispatch(k.value, *args))\
                                     for k in n.keywords],
                           starargs=self.dispatch(n.starargs, *args) if getattr(n, 'starargs', None) else None,
                           kwargs=self.dispatch(n.kwargs, *args) if getattr(n, 'kwargs', None) else None)
 def test_ClassDef(self):
     # class X: pass
     cls = ast.ClassDef('X', [], [], None, None, [ast.Pass()], [])
     self.verify(cls, 'class X:pass')
     # class X(Y): pass
     cls = ast.ClassDef('X', [ast.Name('Y', ast.Load())], [], None, None,
             [ast.Pass()], [])
     self.verify(cls, 'class X(Y):pass')
     # class X(Y=42): pass
     cls = ast.ClassDef('X', [], [ast.keyword('Y', ast.Num(42))], None,
             None, [ast.Pass()], [])
     self.verify(cls, 'class X(Y=42):pass')
     # class X(Z, Y=42): pass
     cls.bases.append(ast.Name('Z', ast.Load()))
     self.verify(cls, 'class X(Z,Y=42):pass')
     # class X(*args): pass
     cls = ast.ClassDef('X', [], [], ast.Name('args', ast.Load()), None,
             [ast.Pass()], [])
     self.verify(cls, 'class X(*args):pass')
     # class X(Y, *args): pass
     cls.bases.append(ast.Name('Y', ast.Load()))
     self.verify(cls, 'class X(Y,*args):pass')
     # class X(**kwargs): pass
     cls = ast.ClassDef('X', [], [], None, ast.Name('kwargs', ast.Load()),
             [ast.Pass()], [])
     self.verify(cls, 'class X(**kwargs):pass')
     # class X(Y, **kwargs): pass
     cls.bases.append(ast.Name('Y', ast.Load()))
     self.verify(cls, 'class X(Y,**kwargs):pass')
     # Decorators
     cls = ast.ClassDef('X', [], [], None, None, [ast.Pass()],
                         [ast.Name('dec1', ast.Load()),
                             ast.Name('dec2', ast.Load())])
     self.verify(cls, '@dec1\n@dec2\nclass X:pass')
Esempio n. 29
0
    def visitCall(self, n, *args):
        self.dispatch(n.func, *args)
        self.dispatch(n.args, *args)
        [ast.keyword(arg=k.arg, value=self.dispatch(k.value, *args)) for k in n.keywords]
        self.dispatch(n.starargs, *args) if getattr(n, 'starargs', None) else None
        self.dispatch(n.kwargs, *args) if getattr(n, 'kwargs', None) else None

        if flags.PY3_VERSION <= 4:
            args, starargs, keywords, kwargs = n.args, n.starargs, n.keywords, n.kwargs
        else:
            args = [a for a in n.args if not isinstance(a, ast.Starred)]
            starargs = [a.value for a in n.args if isinstance(a, ast.Starred)]
            keywords = [k for k in n.keywords if k.arg is not None]
            kwargs = [k.value for k in n.keywords if k.arg is None]
            if len(starargs) > 1 or len(kwargs) > 1:
                raise Exception()
            else:
                starargs = starargs[0] if len(starargs) else None
                kwargs = kwargs[0] if len(kwargs) else None
            
        ty, tyerr = consistency.apply(n.func, n.func.retic_type, args, keywords,
                                      starargs, kwargs)
        
        if not ty:
            raise tyerr
        else:
            n.retic_type = ty
Esempio n. 30
0
def ast_repr(x):
    """Similar to repr(), but returns an AST instead of a String, which when
    evaluated will return the given value."""
    if type(x) in (int, float):
        return ast.Num(n=x)
    elif type(x) in (str, unicode):
        return ast.Str(s=x)
    elif type(x) is list:
        return ast.List(elts=map(ast_repr, x))
    elif type(x) is dict:
        return ast.Dict(keys=map(ast_repr, x.keys()), values=map(ast_repr, x.values()))
    elif type(x) is set:
        return ast.Set(elts=map(ast_repr, x))
    elif type(x) is Literal:
        return x.body
    elif type(x) is Captured:
        return ast.Call(ast.Name(id="Captured"), [x.val, ast_repr(x.name)], [], None, None)
    elif x is None:
        return ast.Name(id="None")
    elif x is True:
        return ast.Name(id="True")
    elif x is False:
        return ast.Name(id="False")
    elif isinstance(x, ast.AST):
        fields = [ast.keyword(a, ast_repr(b)) for a, b in ast.iter_fields(x)]
        return ast.Call(ast.Name(id=x.__class__.__name__), [], fields, None, None)
    raise Exception("Don't know how to ast_repr this: ", x)
Esempio n. 31
0
    def build(self) -> typing.Optional[ast.ClassDef]:
        base_class: typing.Union[ast.Attribute, ast.Name]

        # Create the base class
        if not self.resource.base or self.resource.base.name == "object":
            base_class = ast.Attribute(value=ast.Name(id="marshmallow"),
                                       attr="Schema")
        else:
            if self.resource.base.name in FIELD_TYPES:
                return None
            base_class = ast.Name(id=self.resource.base.name + "Schema")

        # Define the base class
        class_node = ast.ClassDef(
            name=self.resource.name + "Schema",
            bases=[base_class],
            keywords=[],
            decorator_list=[],
            body=[],
        )

        doc_string = f"Marshmallow schema for :class:`commercetools.types.{self.resource.name}`."
        class_node.body.append(ast.Expr(value=ast.Str(s=doc_string)))

        # Add the field definitions
        for prop in self.resource.properties:
            node = self._create_schema_property(prop)
            if node:
                class_node.body.append(node)

        # Add the Meta class
        class_node.body.append(
            ast.ClassDef(
                name="Meta",
                bases=[],
                keywords=[],
                body=[
                    ast.Assign(
                        targets=[ast.Name(id="unknown")],
                        value=ast.Name(id="marshmallow.EXCLUDE"),
                    )
                ],
                decorator_list=[],
            ))

        # Create the post_load() method
        post_load_node = self._create_marshmallow_hook("post_load")
        if self.contains_regex_field:
            post_load_node.body.append(
                self._create_regex_call("_regex", "postprocess"))
        post_load_node.body.append(
            ast.Return(value=ast.Call(
                func=ast.Name(id=f"types.{self.resource.name}"),
                args=[],
                keywords=[ast.keyword(arg=None, value=ast.Name(id="data"))],
            )))
        class_node.body.append(post_load_node)

        # Create the pre_load() method
        if self.contains_regex_field:
            node = self._create_marshmallow_hook("pre_load")
            node.body.append(self._create_regex_call("_regex", "preprocess"))
            node.body.append(ast.Return(value=ast.Name(id="data")))
            class_node.body.append(node)

            node = self._create_marshmallow_hook("pre_dump")
            node.body.append(self._create_regex_call("_regex", "preprocess"))
            node.body.append(ast.Return(value=ast.Name(id="data")))
            class_node.body.append(node)

            node = self._create_marshmallow_hook("post_dump")
            node.body.append(self._create_regex_call("_regex", "postprocess"))
            node.body.append(ast.Return(value=ast.Name(id="data")))
            class_node.body.append(node)

        d_field = self.resource.get_discriminator_field()
        if d_field:
            post_load_node.body.insert(
                0,
                ast.Delete(targets=[
                    ast.Subscript(
                        value=ast.Name(id="data"),
                        slice=ast.Index(value=ast.Str(
                            s=d_field.attribute_name)),
                    )
                ]),
            )
        return class_node
Esempio n. 32
0
    def visit_For(self, node: ast.For):
        # making sure that we don't have for/else case
        if len(node.orelse) > 0:
            # this is illegal syntax
            lines = [n.lineno for n in node.orelse]
            print_src(self.fn_src, lines)
            raise SyntaxError("Illegal Syntax: you are not allowed to use "
                              "for/else in code block")
        # get the target
        iter_ = node.iter
        iter_src = astor.to_source(iter_)
        try:
            iter_obj = eval(iter_src, self.global_, self.local)
            iter_ = list(iter_obj)
        except RuntimeError:
            print_src(self.fn_src, node.iter.lineno)
            raise SyntaxError("Unable to statically evaluate loop iter")
        for v in iter_:
            if not isinstance(v, (int, str)):
                print_src(self.fn_src, node.iter.lineno)
                raise SyntaxError("Loop iter has to be either integer or "
                                  "string, got " + str(type(v)))
        target = node.target
        if not isinstance(target, ast.Name):
            print_src(self.fn_src, node.iter.lineno)
            raise SyntaxError("Unable to parse loop "
                              "target " + astor.to_source(target))

        # if not in debug mode and we are allowed to do so
        if not self.generator.debug and not self.unroll_for and isinstance(iter_obj, range) and \
                self.__loop_self_var(target, node.body):
            # return it as a function call
            _vars = iter_obj.start, iter_obj.stop, iter_obj.step, node.lineno
            _vars = [ast.Num(n=n) for n in _vars]
            keywords = []
            if self.generator.debug:
                keywords = [
                    ast.keyword(arg="f_ln",
                                value=ast.Constant(value=node.lineno))
                ]
            # we redirect the var to one of the scope vars. the index is based
            # on the line number
            index_num = node.lineno
            # create the for statement in the scope
            for_stmt = _kratos.ForStmt(target.id, iter_obj.start,
                                       iter_obj.stop, iter_obj.step)
            self.scope.for_stmt[index_num] = for_stmt
            # set the for iter var
            # redirect the variable to env
            self.scope.iter_var[index_num] = for_stmt.get_iter_var()
            index = ast.Subscript(slice=ast.Index(value=ast.Num(n=index_num)),
                                  value=ast.Attribute(value=ast.Name(
                                      id="scope", ctx=ast.Load()),
                                                      attr="iter_var",
                                                      ctx=ast.Load()))
            for_node = ast.Call(func=ast.Attribute(value=ast.Name(
                id="scope", ctx=ast.Load()),
                                                   attr="for_",
                                                   ctx=ast.Load()),
                                args=[ast.Str(s=target.id)] + _vars,
                                keywords=keywords,
                                ctx=ast.Load())
            body_visitor = StaticElaborationNodeVisitor.NameVisitor(
                target, index)
            body = []
            for i in range(len(node.body)):
                n = self.visit(body_visitor.visit(node.body[i]))
                if isinstance(n, list):
                    for nn in n:
                        body.append(nn)
                else:
                    body.append(n)
            body_node = ast.Call(func=ast.Attribute(attr="loop",
                                                    value=for_node,
                                                    ctx=ast.Load()),
                                 args=body,
                                 keywords=[])
            # create an entry for the target
            self.local[str(target.id)] = 0
            return self.visit(ast.Expr(body_node))
        else:
            new_node = []
            for value in iter_:
                loop_body = copy.deepcopy(node.body)
                for n in loop_body:
                    # need to replace all the reference to
                    visitor = StaticElaborationNodeVisitor.NameVisitor(
                        target, value)
                    n = visitor.visit(n)
                    self.key_pair.append((target.id, value))
                    n = self.visit(n)
                    self.key_pair.pop(len(self.key_pair) - 1)

                    if isinstance(n, list):
                        for n_ in n:
                            new_node.append(n_)
                            self.target_node[n_] = (target.id, value)
                    else:
                        new_node.append(n)
                        self.target_node[n] = (target.id, value)
            return new_node
Esempio n. 33
0
    def visit_If(self, node: ast.If):
        predicate = node.test
        # if it's a var comparison, we change it to eq functional call
        predicate = self.__change_if_predicate(predicate)
        # we only replace stuff if the predicate has something to do with the
        # verilog variable
        predicate_src = astor.to_source(predicate)
        has_var = False
        try:
            predicate_value = eval(predicate_src, self.global_, self.local)
        except (_kratos.exception.InvalidConversionException,
                _kratos.exception.UserException,
                _kratos.exception.VarException) as _:
            has_var = True
            predicate_value = None

        # if's a kratos var, we continue
        if not has_var and not isinstance(predicate_value, _kratos.Var):
            if not isinstance(predicate_value, bool):
                print_src(self.fn_src, predicate.lineno)
                raise SyntaxError("Cannot statically evaluate if predicate")
            if predicate_value:
                for i, n in enumerate(node.body):
                    if_exp = StaticElaborationNodeVisitor(
                        self.generator, self.fn_src, self.scope,
                        self.unroll_for, self.local, self.global_,
                        self.filename, self.scope_ln)
                    node.body[i] = if_exp.visit(n)
                return node.body
            else:
                for i, n in enumerate(node.orelse):
                    if_exp = StaticElaborationNodeVisitor(
                        self.generator, self.fn_src, self.scope,
                        self.unroll_for, self.local, self.global_,
                        self.filename, self.scope_ln)
                    node.orelse[i] = if_exp.visit(n)
                return node.orelse
        else:
            # need to convert the logical operators to either reduced function calls, or
            # expression or
            if_test = LogicOperatorVisitor(self.local, self.global_,
                                           self.filename, self.scope_ln)
            predicate = if_test.visit(node.test)

        expression = node.body
        else_expression = node.orelse

        if self.generator.debug:
            keywords_if = [
                ast.keyword(arg="f_ln", value=ast.Constant(value=node.lineno))
            ]
            # do our best guess
            if len(else_expression) > 0:
                if else_expression[0].lineno != expression[0].lineno:
                    ln = else_expression[0].lineno + 1
                else:
                    ln = else_expression[0].lineno
                keywords_else = [
                    ast.keyword(arg="f_ln", value=ast.Constant(value=ln))
                ]
            else:
                keywords_else = []
        else:
            keywords_if = []
            keywords_else = []
        for key, value in self.key_pair:
            keywords_if.append(ast.keyword(arg=key, value=ast.Str(s=value)))

        if_node = ast.Call(func=ast.Attribute(value=ast.Name(id="scope",
                                                             ctx=ast.Load()),
                                              attr="if_",
                                              ctx=ast.Load()),
                           args=[predicate] + expression,
                           keywords=keywords_if,
                           ctx=ast.Load)
        else_node = ast.Call(func=ast.Attribute(attr="else_",
                                                value=if_node,
                                                ctx=ast.Load()),
                             args=else_expression,
                             keywords=keywords_else)

        return self.visit(ast.Expr(value=else_node))
Esempio n. 34
0
def name(tree):
    "Splices a string value into the quoted code snippet as a Name."
    # TODO: another hard-coded call now assuming `ast.Name`
    return Literal(compat.Call(ast.Attribute(
        value=ast.Name(id='ast', ctx=ast.Load()),
        attr='Name', ctx=ast.Load()), [], [ast.keyword("id", tree)]))
Esempio n. 35
0
def compile_func(gen: 'Generator', func: Callable, strategy: Strategy, with_hooks: bool = False) -> Callable:
    """
    The compilation basically assigns functionality to each of the operator calls as
    governed by the semantics (strategy). Memoization is done with the keys as the `func`,
    the class of the `strategy` and the `with_hooks` argument.

    Args:
        gen (Generator): The generator object containing the function to compile
        func (Callable): The function to compile
        strategy (Strategy): The strategy governing the behavior of the operators
        with_hooks (bool): Whether support for hooks is required

    Returns:
        The compiled function

    """

    if isinstance(strategy, PartialReplayStrategy):
        strategy = strategy.backup_strategy

    if with_hooks:
        cache = CompilationCache.WITH_HOOKS[strategy.__class__]
    else:
        cache = CompilationCache.WITHOUT_HOOKS[strategy.__class__]

    if func in cache:
        return cache[func]

    cache[func] = None

    source_code, start_lineno = inspect.getsourcelines(func)
    source_code = ''.join(source_code)
    f_ast = astutils.parse(textwrap.dedent(source_code))

    # This matches up line numbers with original file and is thus super useful for debugging
    ast.increment_lineno(f_ast, start_lineno - 1)

    #  Remove the ``@generator`` decorator to avoid recursive compilation
    f_ast.decorator_list = [d for d in f_ast.decorator_list
                            if (not isinstance(d, ast.Name) or d.id != 'generator') and
                            (not isinstance(d, ast.Attribute) or d.attr != 'generator') and
                            (not (isinstance(d, ast.Call) and isinstance(d.func,
                                                                         ast.Name)) or d.func.id != 'generator')]

    #  Get all the external dependencies of this function.
    #  We rely on a modified closure function adopted from the ``inspect`` library.
    closure_vars = getclosurevars_recursive(func, f_ast)
    g = {**closure_vars.nonlocals.copy(), **closure_vars.globals.copy()}
    known_ops: Set[str] = strategy.get_known_ops()
    known_methods: Set[str] = strategy.get_known_methods()
    op_info_constructor = OpInfoConstructor()
    delayed_compilations: List[Tuple[Generator, str]] = []

    ops = {}
    handlers = {}
    op_infos = {}
    op_idx: int = 0
    composition_cnt: int = 0
    for n in astutils.preorder_traversal(f_ast):
        if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id in known_ops:
            #  Rename the function call, and assign a new function to be called during execution.
            #  This new function is determined by the semantics (strategy) being used for compilation.
            #  Also determine if there any eligible hooks for this operator call.
            op_idx += 1
            handler_idx = len(handlers)
            op_info: OpInfo = op_info_constructor.get(n, gen.name, gen.group)

            n.keywords.append(ast.keyword(arg='model', value=ast.Name(_GEN_MODEL_VAR, ctx=ast.Load())))

            n.keywords.append(ast.keyword(arg='op_info', value=ast.Name(f"_op_info_{op_idx}", ctx=ast.Load())))
            op_infos[f"_op_info_{op_idx}"] = op_info

            n.keywords.append(ast.keyword(arg='handler', value=ast.Name(f"_handler_{handler_idx}", ctx=ast.Load())))
            handler = strategy.get_op_handler(op_info)
            handlers[f"_handler_{handler_idx}"] = handler

            if not with_hooks:
                n.func = astutils.parse(f"{_GEN_STRATEGY_VAR}.generic_op").value
            else:
                n.keywords.append(ast.keyword(arg=_GEN_HOOK_VAR, value=ast.Name(_GEN_HOOK_VAR, ctx=ast.Load())))
                n.keywords.append(ast.keyword(arg=_GEN_STRATEGY_VAR, value=ast.Name(_GEN_STRATEGY_VAR, ctx=ast.Load())))

                n.func.id = _GEN_HOOK_WRAPPER
                ops[_GEN_HOOK_WRAPPER] = hook_wrapper

            if returns_lambda(handler):
                n.func = ast.Call(func=n.func, args=n.args[:], keywords=n.keywords[:])
                n.keywords = []
                n.args = [n.args[0]]

            ast.fix_missing_locations(n)

        elif isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id in known_methods:
            #  Similar in spirit to the known_ops case, just much less fancy stuff to do.
            #  Only need to get the right handler which we will achieve by simply making this
            #  a method call instead of a regular call.
            n.func = ast.Attribute(value=ast.Name(_GEN_STRATEGY_VAR, ctx=ast.Load()), attr=n.func.id, ctx=ast.Load())
            ast.fix_missing_locations(n)

        elif isinstance(n, ast.Call):
            #  Try to check if it is a call to a Generator
            #  TODO : Can we be more sophisticated in our static analysis here
            try:
                function = eval(astunparse.unparse(n.func), g)
                if isinstance(function, Generator):
                    call_id = f"{_GEN_COMPOSITION_ID}_{composition_cnt}"
                    composition_cnt += 1
                    n.func.id = call_id
                    n.keywords.append(ast.keyword(arg=_GEN_EXEC_ENV_VAR,
                                                  value=ast.Name(_GEN_EXEC_ENV_VAR, ctx=ast.Load())))
                    n.keywords.append(ast.keyword(arg=_GEN_STRATEGY_VAR,
                                                  value=ast.Name(_GEN_STRATEGY_VAR, ctx=ast.Load())))
                    n.keywords.append(ast.keyword(arg=_GEN_MODEL_VAR,
                                                  value=ast.Name(_GEN_MODEL_VAR, ctx=ast.Load())))
                    n.keywords.append(ast.keyword(arg=_GEN_HOOK_VAR,
                                                  value=ast.Name(_GEN_HOOK_VAR, ctx=ast.Load())))
                    ast.fix_missing_locations(n)

                    #  We delay compilation to handle mutually recursive generators
                    delayed_compilations.append((function, call_id))

            except:
                pass

    #  Add the execution environment argument to the function
    f_ast.args.kwonlyargs.append(ast.arg(arg=_GEN_EXEC_ENV_VAR, annotation=None))
    f_ast.args.kw_defaults.append(ast.NameConstant(value=None))

    #  Add the strategy argument to the function
    f_ast.args.kwonlyargs.append(ast.arg(arg=_GEN_STRATEGY_VAR, annotation=None))
    f_ast.args.kw_defaults.append(ast.NameConstant(value=None))

    #  Add the strategy argument to the function
    f_ast.args.kwonlyargs.append(ast.arg(arg=_GEN_MODEL_VAR, annotation=None))
    f_ast.args.kw_defaults.append(ast.NameConstant(value=None))

    #  Add the hook argument to the function
    f_ast.args.kwonlyargs.append(ast.arg(arg=_GEN_HOOK_VAR, annotation=None))
    f_ast.args.kw_defaults.append(ast.NameConstant(value=None))
    ast.fix_missing_locations(f_ast)

    #  New name so it doesn't clash with original
    func_name = f"{_GEN_COMPILED_TARGET_ID}_{len(cache)}"

    g.update({k: v for k, v in ops.items()})
    g.update({k: v for k, v in handlers.items()})
    g.update({k: v for k, v in op_infos.items()})

    module = ast.Module()
    module.body = [f_ast]

    #  Passing ``g`` to exec allows us to execute all the new functions
    #  we assigned to every operator call in the previous AST walk
    exec(compile(module, filename=inspect.getabsfile(func), mode="exec"), g)
    result = g[func.__name__]

    if inspect.ismethod(func):
        result = result.__get__(func.__self__, func.__self__.__class__)

    #  Restore the correct namespace so that tracebacks contain actual function names
    g[gen.name] = gen
    g[func_name] = result

    cache[func] = result

    #  Handle the delayed compilations now that we have populated the cache
    for gen, call_id in delayed_compilations:
        compiled_func = compile_func(gen, gen.func, strategy, with_hooks)
        if gen.caching and isinstance(strategy, DfsStrategy):
            #  Add instructions for using cached result if any
            g[call_id] = cache_wrapper(compiled_func)

        else:
            g[call_id] = compiled_func

    return result
Esempio n. 36
0
""".format(comment=docstring_header_and_return_str)

config_tbl_ast = Assign(
    targets=[Name("config_tbl", Store())],
    value=Call(
        func=Name("Table", Load()),
        args=[
            set_value("config_tbl"),
            Name("metadata", Load()),
            Call(
                func=Name("Column", Load()),
                args=[set_value("dataset_name"),
                      Name("String", Load())],
                keywords=[
                    keyword(arg="doc",
                            value=set_value("name of dataset"),
                            identifier=None),
                    keyword(arg="default",
                            value=set_value("mnist"),
                            identifier=None),
                    keyword(arg="primary_key",
                            value=set_value(True),
                            identifier=None),
                ],
                expr=None,
                expr_func=None,
            ),
            Call(
                func=Name("Column", Load()),
                args=[set_value("tfds_dir"),
                      Name("String", Load())],
def _create_schema_field(param: ServiceParameter):
    """Generate a field assignment for a marshmallow schema"""
    keywords = []
    imports = []
    methods = []
    code_name = snakeit(param.name)
    if code_name != param.name:
        keywords.append(
            ast.keyword(arg="data_key", value=ast.Str(s=param.name,
                                                      kind=None)))
    if not param.required:
        keywords.append(
            ast.keyword(arg="required",
                        value=ast.Constant(value=False, kind=None)))

    if param.name.startswith("/"):
        placeholder = param.extra_data["(placeholderParam)"]
        code_name = snakeit(placeholder["paramName"])
        imports.append(("marshmallow", "fields"))
        imports.append(("marshmallow", ))
        serialize_func = ast.Call(
            func=ast.Attribute(value=ast.Name(id="fields"), attr="Dict"),
            args=[],
            keywords=[],
        )

        # TODO: can break if there is a suffix
        key_name = placeholder["template"].replace(
            "<%s>" % placeholder["placeholder"], "")
        code = ast.parse(
            textwrap.dedent(
                """
            @marshmallow.post_dump
            def _%(target_name)s_post_dump(self, data, **kwrags):
                values = data.pop('%(target_name)s')
                if not values:
                    return data
                for key, val in values.items():
                    data[f"%(key_name)s{key}"] = val
                return data

            @marshmallow.pre_load
            def _%(target_name)s_post_load(self, data, **kwrags):
                items = {}
                for key in list(data.keys()):
                    if key.startswith("%(key_name)s"):
                        items[key[%(key_len)d:]] = data[key]
                        del data[key]
                data["%(target_name)s"] = items
                return data
        """ % {
                    "target_name": code_name,
                    "key_name": key_name,
                    "key_len": len(key_name),
                }))
        methods.extend(code.body)

    elif param.type == "string":
        imports.append(("commercetools.helpers", "OptionalList"))
        imports.append(("marshmallow", "fields"))
        serialize_func = ast.Call(
            func=ast.Name(id="OptionalList"),
            args=[
                ast.Call(
                    func=ast.Attribute(value=ast.Name(id="fields"),
                                       attr="String"),
                    args=[],
                    keywords=[],
                )
            ],
            keywords=keywords,
        )
    elif param.type == "number":
        imports.append(("marshmallow", "fields"))
        serialize_func = ast.Call(
            func=ast.Attribute(value=ast.Name(id="fields"), attr="Int"),
            args=[],
            keywords=keywords,
        )

    elif param.type == "boolean":
        keywords.append(
            ast.keyword(arg="missing",
                        value=ast.Constant(value=False, kind=None)))
        imports.append(("marshmallow", "fields"))
        serialize_func = ast.Call(
            func=ast.Attribute(value=ast.Name(id="fields"), attr="Bool"),
            args=[],
            keywords=keywords,
        )
    elif param.type == "file":
        return None, []
    else:
        raise NotImplementedError(param)

    node = ast.Assign(targets=[ast.Name(id=code_name)],
                      value=serialize_func,
                      simple=1)
    return node, methods, imports
Esempio n. 38
0
    def _get_property_field(self, prop):
        if prop.type is None:
            return ast.Call(
                func=ast.Name(id=FIELD_TYPES["object"]),
                args=[],
                keywords=[
                    ast.keyword(arg="allow_none", value=ast.NameConstant(True))
                ],
            )
        elif prop.type.enum:
            return ast.Call(
                func=ast.Name(id="marshmallow_enum.EnumField"),
                args=[
                    ast.Attribute(value=ast.Name(id="types"),
                                  attr=prop.type.name)
                ],
                keywords=[
                    ast.keyword(arg="by_value", value=ast.NameConstant(True))
                ],
            )

        elif prop.type.discriminator:
            return self._create_discriminator_field(prop.type)

        elif prop.type.name.startswith("/"):
            return ast.Call(func=ast.Name(id=prop.type.name + "Field"),
                            args=[],
                            keywords=[])

        elif prop.type.name in FIELD_TYPES:
            node = ast.Call(
                func=ast.Name(id=FIELD_TYPES[prop.type.name]),
                args=[],
                keywords=[
                    ast.keyword(arg="allow_none", value=ast.NameConstant(True))
                ],
            )
            if prop.type.name == "array":
                assert prop.items, f"The array property {prop.name} has no items"
                assert prop.items_types

                # TODO: We for now assume that the items are all subclasses of
                # the first item. We shouldn't do that :-)
                if prop.items_types[0].discriminator:
                    node.args.append(
                        self._create_discriminator_field(prop.items_types[0]))
                else:
                    node.args.append(
                        self._create_nested_field(prop.items_types[0]))
            return node

        # Dict Field
        elif "asMap" in prop.type.annotations:
            return ast.Call(
                func=ast.Name(id=prop.type.name + "Field"),
                args=[],
                keywords=[
                    ast.keyword(arg="allow_none", value=ast.NameConstant(True))
                ],
            )

        elif prop.type.base and prop.type.base.name == "string":
            return ast.Call(func=ast.Name(id="marshmallow.fields.String"),
                            args=[],
                            keywords=[])

        else:
            return self._create_nested_field(prop.type)
Esempio n. 39
0
def py_emit(node: ast.Call, ctx: Context):
    py_emit(node.func, ctx)

    has_star = False
    has_key = False
    has_star_star = False

    for each in node.args:
        if isinstance(each, ast.Starred):
            has_star = True
            break
    for each in node.keywords:
        if each.arg:
            has_key = True
            break
    for each in node.keywords:
        if each.arg is None:
            has_star_star = True
            break

    # positional arguments
    if has_star or has_star_star:
        arg_count = 0
        arg_tuple_count = 0
        for each in node.args:
            if not isinstance(each, ast.Starred):
                py_emit(each, ctx)
                arg_count += 1
            else:
                if arg_count:
                    ctx.bc.append(
                        Instr("BUILD_TUPLE", arg_count, lineno=node.lineno))
                    arg_tuple_count += 1
                    arg_count = 0
                py_emit(each.value, ctx)
                arg_tuple_count += 1

        if arg_count:
            ctx.bc.append(Instr("BUILD_TUPLE", arg_count, lineno=node.lineno))
            arg_tuple_count += 1

        if arg_tuple_count > 1:
            ctx.bc.append(
                Instr("BUILD_TUPLE_UNPACK_WITH_CALL",
                      arg_tuple_count,
                      lineno=node.lineno))
        elif arg_tuple_count == 1:
            pass
        elif arg_tuple_count == 0:
            ctx.bc.append(Instr("BUILD_TUPLE", 0, lineno=node.lineno))
    else:
        for each in node.args:
            py_emit(each, ctx)

    # keyword arguments
    if has_star or has_star_star:
        karg_pack_count = 0
        keys = []
        values = []
        karg_count = 0
        # use dummy node handle trailing keyword arguments
        dummy_node = ast.keyword(arg=None)
        node.keywords.append(dummy_node)
        for each in node.keywords:
            if each.arg:
                keys.append(each.arg)
                values.append(each.value)
                karg_count += 1
            else:
                if karg_count:
                    karg_pack_count += 1
                    if karg_count > 1:
                        for value in values:
                            py_emit(value, ctx)
                        ctx.bc.append(
                            Instr("LOAD_CONST",
                                  tuple(keys),
                                  lineno=node.lineno))
                        ctx.bc.append(
                            Instr("BUILD_CONST_KEY_MAP",
                                  karg_count,
                                  lineno=node.lineno))
                    elif karg_count == 1:
                        ctx.bc.append(
                            Instr("LOAD_CONST", keys[0], lineno=node.lineno))
                        py_emit(values[0], ctx)
                        ctx.bc.append(Instr("BUILD_MAP", 1,
                                            lineno=node.lineno))
                    keys = []
                    values = []
                    karg_count = 0
                if each is dummy_node:
                    break
                py_emit(each.value, ctx)
                karg_pack_count += 1
        node.keywords.pop(-1)  # pop dummy node
        if karg_pack_count > 1:
            ctx.bc.append(
                Instr("BUILD_MAP_UNPACK_WITH_CALL",
                      karg_pack_count,
                      lineno=node.lineno))
    else:
        keys = []
        for each in node.keywords:
            py_emit(each.value, ctx)
            keys.append(each.arg)
        if keys:
            ctx.bc.append(Instr("LOAD_CONST", tuple(keys), lineno=node.lineno))

    if has_star or has_star_star:
        ctx.bc.append(
            Instr("CALL_FUNCTION_EX",
                  has_star_star | has_key,
                  lineno=node.lineno))
    elif has_key:
        ctx.bc.append(
            Instr("CALL_FUNCTION_KW",
                  len(node.args) + len(node.keywords),
                  lineno=node.lineno))
    else:
        ctx.bc.append(
            Instr('CALL_FUNCTION', len(node.args), lineno=node.lineno))
Esempio n. 40
0
    def _gen_extractors(self, request):
        stmts = []
        jextractors = request.config.get("extract-jsonpath", BetterDict())
        for varname in jextractors:
            cfg = ensure_is_dict(jextractors, varname, "jsonpath")
            stmts.append(ast.Assign(
                targets=[ast.Name(id=varname, ctx=ast.Store())],
                value=ast.Call(
                    func=ast.Attribute(
                        value=ast.Name(id="response", ctx=ast.Load()),
                        attr="extract_jsonpath",
                        ctx=ast.Load()
                    ),
                    args=[self.gen_expr(cfg['jsonpath']), self.gen_expr(cfg.get('default', 'NOT_FOUND'))],
                    keywords=[],
                    starargs=None,
                    kwargs=None
                )
            ))

        extractors = request.config.get("extract-regexp", BetterDict())
        for varname in extractors:
            cfg = ensure_is_dict(extractors, varname, "regexp")
            # TODO: support non-'body' value of 'subject'
            stmts.append(ast.Assign(
                targets=[ast.Name(id=varname, ctx=ast.Store())],
                value=ast.Call(
                    func=ast.Attribute(
                        value=ast.Name(id="response", ctx=ast.Load()),
                        attr="extract_regex",
                        ctx=ast.Load()
                    ),
                    args=[self.gen_expr(cfg['regexp']), self.gen_expr(cfg.get('default', 'NOT_FOUND'))],
                    keywords=[],
                    starargs=None,
                    kwargs=None
                )
            ))

        # TODO: css/jquery extractor?

        xpath_extractors = request.config.get("extract-xpath", BetterDict())
        for varname in xpath_extractors:
            cfg = ensure_is_dict(xpath_extractors, varname, "xpath")
            parser_type = 'html' if cfg.get('use-tolerant-parser', True) else 'xml'
            validate = cfg.get('validate-xml', False)
            stmts.append(ast.Assign(
                targets=[ast.Name(id=varname, ctx=ast.Store())],
                value=ast.Call(
                    func=ast.Attribute(
                        value=ast.Name(id="response", ctx=ast.Load()),
                        attr="extract_xpath",
                        ctx=ast.Load()
                    ),
                    args=[self.gen_expr(cfg['xpath'])],
                    keywords=[ast.keyword(arg="default", value=cfg.get('default', 'NOT_FOUND')),
                              ast.keyword(arg="parser_type", value=parser_type),
                              ast.keyword(arg="validate", value=validate)],
                    starargs=None,
                    kwargs=None,
                )
            ))

        return stmts
Esempio n. 41
0
    def gen_request_lines(self, req):
        apiritif_http = ast.Attribute(value=ast.Name(id='apiritif', ctx=ast.Load()),
                                      attr='http', ctx=ast.Load())
        target = ast.Name(id='target', ctx=ast.Load())
        requestor = target if self.__access_method == "target" else apiritif_http

        method = req.method.lower()
        think_time = dehumanize_time(req.priority_option('think-time', default=None))
        named_args = self._extract_named_args(req)

        if req.label:
            label = req.label
        else:
            label = req.url

        lines = []

        tran = ast.Attribute(value=ast.Name(id='apiritif', ctx=ast.Load()),
                             attr="transaction", ctx=ast.Load())
        transaction = ast.With(
            context_expr=ast.Call(
                func=tran,
                args=[self.gen_expr(label)],
                keywords=[],
                starargs=None,
                kwargs=None
            ),
            optional_vars=None,
            body=[
                ast.Assign(
                    targets=[
                        ast.Name(id="response", ctx=ast.Store())
                    ],
                    value=ast.Call(
                        func=ast.Attribute(value=requestor, attr=method, ctx=ast.Load()),
                        args=[self.gen_expr(req.url)],
                        keywords=[ast.keyword(arg=name, value=self.gen_expr(value))
                                  for name, value in iteritems(named_args)],
                        starargs=None,
                        kwargs=None
                    )
                )
            ],
        )
        lines.append(transaction)

        lines.extend(self._gen_assertions(req))
        lines.extend(self._gen_jsonpath_assertions(req))
        lines.extend(self._gen_xpath_assertions(req))
        lines.extend(self._gen_extractors(req))

        if think_time:
            lines.append(ast.Expr(ast.Call(func=ast.Attribute(value=ast.Name(id="time", ctx=ast.Load()),
                                                              attr="sleep",
                                                              ctx=ast.Load()),
                                           args=[self.gen_expr(think_time)],
                                           keywords=[],
                                           starargs=None,
                                           kwargs=None)))

        return lines
Esempio n. 42
0
    def test_empty_init(self):
        # Jython 2.5.0 did not allow empty constructors for many ast node types
        # but CPython ast nodes do allow this.  For the moment, I don't see a
        # reason to allow construction of the super types (like ast.AST and
        # ast.stmt) as well as the op types that are implemented as enums in
        # Jython (like boolop), but I've left them in but commented out for
        # now.  We may need them in the future since CPython allows this, but
        # it may fall under implementation detail.

        #ast.AST()
        ast.Add()
        ast.And()
        ast.Assert()
        ast.Assign()
        ast.Attribute()
        ast.AugAssign()
        ast.AugLoad()
        ast.AugStore()
        ast.BinOp()
        ast.BitAnd()
        ast.BitOr()
        ast.BitXor()
        ast.BoolOp()
        ast.Break()
        ast.Call()
        ast.ClassDef()
        ast.Compare()
        ast.Continue()
        ast.Del()
        ast.Delete()
        ast.Dict()
        ast.Div()
        ast.Ellipsis()
        ast.Eq()
        ast.Exec()
        ast.Expr()
        ast.Expression()
        ast.ExtSlice()
        ast.FloorDiv()
        ast.For()
        ast.FunctionDef()
        ast.GeneratorExp()
        ast.Global()
        ast.Gt()
        ast.GtE()
        ast.If()
        ast.IfExp()
        ast.Import()
        ast.ImportFrom()
        ast.In()
        ast.Index()
        ast.Interactive()
        ast.Invert()
        ast.Is()
        ast.IsNot()
        ast.LShift()
        ast.Lambda()
        ast.List()
        ast.ListComp()
        ast.Load()
        ast.Lt()
        ast.LtE()
        ast.Mod()
        ast.Module()
        ast.Mult()
        ast.Name()
        ast.Not()
        ast.NotEq()
        ast.NotIn()
        ast.Num()
        ast.Or()
        ast.Param()
        ast.Pass()
        ast.Pow()
        ast.Print()
        ast.RShift()
        ast.Raise()
        ast.Repr()
        ast.Return()
        ast.Slice()
        ast.Store()
        ast.Str()
        ast.Sub()
        ast.Subscript()
        ast.Suite()
        ast.TryExcept()
        ast.TryFinally()
        ast.Tuple()
        ast.UAdd()
        ast.USub()
        ast.UnaryOp()
        ast.While()
        ast.With()
        ast.Yield()
        ast.alias()
        ast.arguments()
        #ast.boolop()
        #ast.cmpop()
        ast.comprehension()
        #ast.excepthandler()
        #ast.expr()
        #ast.expr_context()
        ast.keyword()
Esempio n. 43
0
    async def async_eval(self, code, **kwargs):
        # Note to self: please don't set globals here as they will be lost.
        # Don't clutter locals
        locs = {}
        # Restore globals later
        globs = globals().copy()
        # This code saves __name__ and __package into a kwarg passed to the function.
        # It is set before the users code runs to make sure relative imports work
        global_args = "_globs"
        while global_args in globs.keys():
            # Make sure there's no name collision, just keep prepending _s
            global_args = "_" + global_args
        kwargs[global_args] = {}
        for glob in ["__name__", "__package__"]:
            # Copy data to args we are sending
            kwargs[global_args][glob] = globs[glob]

        root = ast.parse(code, 'exec')
        code = root.body
        # If we can use it as a lambda return (but multiline)
        if isinstance(code[-1], ast.Expr):
            # Change it to a return statement
            code[-1] = ast.copy_location(ast.Return(code[-1].value), code[-1])
        # globals().update(**<global_args>)
        glob_copy = ast.Expr(ast.Call(func=ast.Attribute(value=ast.Call(func=ast.Name(id='globals', ctx=ast.Load()),
                                                                        args=[], keywords=[]),
                                                         attr='update', ctx=ast.Load()),
                                      args=[], keywords=[ast.keyword(arg=None,
                                                                     value=ast.Name(id=global_args, ctx=ast.Load()))]))
        glob_copy.lineno = 0
        glob_copy.col_offset = 0
        ast.fix_missing_locations(glob_copy)
        code.insert(0, glob_copy)
        args = []
        for a in list(map(lambda x: ast.arg(x, None), kwargs.keys())):
            a.lineno = 0
            a.col_offset = 0
            args += [a]
        fun = ast.AsyncFunctionDef('tmp', ast.arguments(
            args=[],
            vararg=None,
            kwonlyargs=args,
            posonlyargs=[],
            kwarg=None,
            defaults=[],
            kw_defaults=[None for i in range(len(args))]), code, [], None
        )
        fun.lineno = 0
        fun.col_offset = 0
        mod = ast.Module([fun], type_ignores=[])
        comp = compile(mod, '<string>', 'exec')

        exec(comp, {}, locs)

        with self.temp_stdio() as out:
            result = await locs["tmp"](**kwargs)
            try:
                globals().clear()
                # Inconsistent state
            finally:
                globals().update(**globs)
            return result, out.getvalue()
Esempio n. 44
0
 def visit_Call(self, node):
     new_node = self.generic_visit(node)
     if isinstance(node.func, ast.Name) and node.func.id in self.functions:
         new_node.keywords.append(ast.keyword(arg='evaluate', value=ast.NameConstant(value=False, ctx=ast.Load())))
     return new_node
Esempio n. 45
0
async def meval(code, globs, **kwargs):
    # Note to self: please don't set globals here as they will be lost.
    # Don't clutter locals
    locs = {}
    # Restore globals later
    globs = globs.copy()
    # This code saves __name__ and __package into a kwarg passed to the func.
    # It is set before the users code runs to make sure relative imports work
    global_args = "_globs"
    while global_args in globs.keys():
        # Make sure there's no name collision, just keep prepending _s
        global_args = "_" + global_args
    kwargs[global_args] = {}
    for glob in ["__name__", "__package__"]:
        # Copy data to args we are sending
        kwargs[global_args][glob] = globs[glob]

    root = ast.parse(code, "exec")
    code = root.body

    ret_name = "_ret"
    ok = False
    while True:
        if ret_name in globs.keys():
            ret_name = "_" + ret_name
            continue
        for node in ast.walk(root):
            if isinstance(node, ast.Name) and node.id == ret_name:
                ret_name = "_" + ret_name
                break
            ok = True
        if ok:
            break

    if not code:
        return None

    if not any(isinstance(node, ast.Return) for node in code):
        for i in range(len(code)):
            if isinstance(code[i], ast.Expr):
                if (i == len(code) - 1
                        or not isinstance(code[i].value, ast.Call)):
                    code[i] = ast.copy_location(
                        ast.Expr(
                            ast.Call(func=ast.Attribute(value=ast.Name(
                                id=ret_name, ctx=ast.Load()),
                                attr="append",
                                ctx=ast.Load()),
                                args=[code[i].value],
                                keywords=[])), code[-1])
    else:
        for node in code:
            if isinstance(node, ast.Return):
                node.value = ast.List(elts=[node.value], ctx=ast.Load())

    code.append(
        ast.copy_location(
            ast.Return(value=ast.Name(id=ret_name, ctx=ast.Load())), code[-1]))

    # globals().update(**<global_args>)
    glob_copy = ast.Expr(
        ast.Call(
            func=ast.Attribute(value=ast.Call(func=ast.Name(id="globals",
                                                            ctx=ast.Load()),
                                              args=[],
                                              keywords=[]),
                               attr="update",
                               ctx=ast.Load()),
            args=[],
            keywords=[
                ast.keyword(arg=None,
                            value=ast.Name(id=global_args, ctx=ast.Load()))
            ]))
    ast.fix_missing_locations(glob_copy)
    code.insert(0, glob_copy)
    ret_decl = ast.Assign(targets=[ast.Name(id=ret_name, ctx=ast.Store())],
                          value=ast.List(elts=[], ctx=ast.Load()))
    ast.fix_missing_locations(ret_decl)
    code.insert(1, ret_decl)
    args = []
    for a in list(map(lambda x: ast.arg(x, None), kwargs.keys())):
        ast.fix_missing_locations(a)
        args += [a]
    args = ast.arguments(args=[],
                         vararg=None,
                         kwonlyargs=args,
                         kwarg=None,
                         defaults=[],
                         kw_defaults=[None for i in range(len(args))])
    args.posonlyargs = []
    fun = ast.AsyncFunctionDef(name="tmp",
                               args=args,
                               body=code,
                               decorator_list=[],
                               returns=None)
    ast.fix_missing_locations(fun)
    mod = ast.parse("")
    mod.body = [fun]
    comp = compile(mod, "<string>", "exec")

    exec(comp, {}, locs)

    r = await locs["tmp"](**kwargs)
    for i in range(len(r)):
        if hasattr(r[i], "__await__"):
            r[i] = await r[i]  # workaround for 3.5
    i = 0
    while i < len(r) - 1:
        if r[i] is None:
            del r[i]
        else:
            i += 1
    if len(r) == 1:
        [r] = r
    elif not r:
        r = None
    return r
    def make_update_method(self, method, node, return_obj, module_name):
        """Create the `.update_by_*(self, id, actions, ...)` method"""
        response_schema_name = return_obj.name + "Schema"
        self.add_import_statement(
            module_name,
            f"commercetools._schemas.{return_obj.package_name}",
            response_schema_name,
        )

        input_obj = self._types.get(method.input_type)
        if not input_obj:
            return
        action_obj = self._types.get(method.input_type + "Action")
        input_schema_name = input_obj.name + "Schema"

        self.add_import_statement(
            module_name, f"commercetools.types.{input_obj.package_name}",
            input_obj.name)
        self.add_import_statement(
            module_name,
            f"commercetools.types.{action_obj.package_name}",
            action_obj.name,
        )
        self.add_import_statement(
            module_name,
            f"commercetools._schemas.{input_obj.package_name}",
            input_schema_name,
        )

        node.args.args.append(
            ast.arg(
                arg="actions",
                annotation=ast.Subscript(
                    value=ast.Name(id="typing.List"),
                    slice=ast.Index(value=ast.Name(id=action_obj.name)),
                ),
            ))
        node.args.kwonlyargs.append(
            ast.arg(arg="force_update", annotation=ast.Name(id="bool")))
        node.args.kw_defaults.append(ast.Constant(value=False, kind=None))

        # update_action = types.ProductUpdate(version=version, actions=actions)
        node.body.append(
            ast.Assign(
                targets=[ast.Name(id="update_action")],
                value=ast.Call(
                    func=ast.Name(id=input_obj.name),
                    args=[],
                    keywords=[
                        ast.keyword(arg="version",
                                    value=ast.Name(id="version")),
                        ast.keyword(arg="actions",
                                    value=ast.Name(id="actions")),
                    ],
                ),
            ))

        node.body.append(
            ast.Return(
                self._call_client(
                    method=f"_post",
                    endpoint=_create_endpoint_fstring(method.path),
                    params=ast.Name("params"),
                    data_object=ast.Name("update_action"),
                    request_schema_cls=ast.Name(id=input_schema_name),
                    response_schema_cls=ast.Name(id=response_schema_name),
                    force_update=ast.Name(id="force_update"),
                )))
        return node
Esempio n. 47
0
	def __build_function(self, dom_name, full_name, func_params):

		assert 'name' in func_params
		func_name = func_params['name']

		docstr = self.__build_desc_string(dom_name, func_name, func_params)

		args = [ast.arg('self', None)]
		message_params = []
		func_body = []

		if docstr:
			func_body.append(ast.Expr(ast.Str("\n"+docstr+"\n\t\t")))

		for param in func_params.get("parameters", []):

			argname = param['name']


			param_optional = param.get("optional", False)

			if param_optional is False:
				message_params.append(ast.keyword(argname, ast.Name(id=argname, ctx=ast.Load())))
				args.append(ast.arg(argname, None))
				if self.do_debug_prints:
					func_body.append(self.__build_debug_print(argname, argname))



			param_type = param.get("type", None)
			if param_type in CHECKS:
				if param_optional:
					check = self.__build_conditional_arg_check(argname, CHECKS[param_type])
				else:
					check = self.__build_unconditional_arg_check(argname, CHECKS[param_type])

				if check:
					func_body.append(check)




		optional_params = [param.get("name") for param in func_params.get("parameters", []) if param.get("optional", False)]
		func_kwargs = None
		if len(optional_params):


			value = ast.List(elts=[ast.Str(s=param, ctx=ast.Store()) for param in optional_params], ctx=ast.Load())
			create_list = ast.Assign(targets=[ast.Name(id='expected', ctx=ast.Store())], value=value)

			func_body.append(create_list)

			passed_arg_list = ast.Assign(targets=[ast.Name(id='passed_keys', ctx=ast.Store())],
				value=ast.Call(func=ast.Name(id='list', ctx=ast.Load()),
				args=[ast.Call(func=ast.Attribute(value=ast.Name(id='kwargs', ctx=ast.Load()), attr='keys', ctx=ast.Load()), args=[], keywords=[])],
				keywords=[]))

			func_body.append(passed_arg_list)

			comprehension = ast.comprehension(target=ast.Name(id='key', ctx=ast.Store()), iter=ast.Name(id='passed_keys', ctx=ast.Load()), ifs=[], is_async=False)
			comparator = ast.Name(id='expected', ctx=ast.Load())

			listcomp = ast.ListComp(elt=ast.Compare(left=ast.Name(id='key', ctx=ast.Load()), ops=[ast.In()], comparators=[comparator]), generators=[comprehension])

			check_message = ast.BinOp(
					left         = ast.Str(s="Allowed kwargs are {}. Passed kwargs: %s".format(optional_params)),
					op           = ast.Mod(),
					right        = ast.Name(id='passed_keys', ctx=ast.Load()),
					lineno       = self.__get_line())

			kwarg_check = ast.Assert(test=ast.Call(func=ast.Name(id='all', ctx=ast.Load()), args=[listcomp], keywords=[]), msg=check_message)
			func_body.append(kwarg_check)

			func_kwargs = ast.Name(id='kwargs', ctx=ast.Load())


		fname = "{}.{}".format(dom_name, func_name)
		fname = ast.Str(s=fname, ctx=ast.Load())


		if (sys.version_info[0], sys.version_info[1]) == (3, 5) or \
			(sys.version_info[0], sys.version_info[1]) == (3, 6) or \
			(sys.version_info[0], sys.version_info[1]) == (3, 7) or \
			(sys.version_info[0], sys.version_info[1]) == (3, 8):

			# More irritating minor semantic differences in the AST between 3.4 and 3.5
			if func_kwargs:
				message_params.append(ast.keyword(arg=None, value=ast.Name(id='kwargs', ctx=ast.Load())))

			communicate_call = ast.Call(
					func=ast.Attribute(value=ast.Name(id='self', ctx=ast.Load()), ctx=ast.Load(), attr='synchronous_command'),
					args=[fname],
					keywords=message_params)

		elif (sys.version_info[0], sys.version_info[1]) == (3,4):

			communicate_call = ast.Call(
					func=ast.Attribute(value=ast.Name(id='self', ctx=ast.Load()), ctx=ast.Load(), attr='synchronous_command'),
					args=[fname],
					kwargs=func_kwargs,
					keywords=message_params)
		else:
			print("Version:", sys.version_info)
			raise RuntimeError("This script only functions on python 3.4, 3.5, 3.6, or 3.7. Active python version {}.{}".format(*sys.version_info))


		do_communicate = ast.Assign(targets=[ast.Name(id='subdom_funcs', ctx=ast.Store())], value=communicate_call)
		func_ret = ast.Return(value=ast.Name(id='subdom_funcs', ctx=ast.Load()))


		if len(optional_params) and self.do_debug_prints:
			func_body.append(self.__build_debug_print('kwargs', 'kwargs'))

		func_body.append(do_communicate)
		func_body.append(func_ret)

		if len(optional_params):
			kwarg = ast.arg(arg='kwargs', annotation=None)
		else:
			kwarg = None


		sig = ast.arguments(
					args=args,
					vararg=None,
					varargannotation=None,
					posonlyargs=[],
					kwonlyargs=[],
					kwarg=kwarg,
					kwargannotation=None,
					defaults=[],
					kw_defaults=[])

		func = ast.FunctionDef(
			name = "{}_{}".format(full_name, func_name),
			args = sig,
			body = func_body,
			decorator_list = [],
			lineno     = self.__get_line(),
			col_offset = 0,
			)

		return func
Esempio n. 48
0
    def _compile_directive_call_assets(self, el, options):
        """ This special 't-call' tag can be used in order to aggregate/minify javascript and css assets"""
        if len(el):
            raise SyntaxError("t-call-assets cannot contain children nodes")

        # nodes = self._get_asset_nodes(xmlid, options, css=css, js=js, debug=values.get('debug'), async=async, values=values)
        #
        # for index, (tagName, t_attrs, content) in enumerate(nodes):
        #     if index:
        #         append('\n        ')
        #     append('<')
        #     append(tagName)
        #
        #     self._post_processing_att(tagName, t_attrs, options)
        #     for name, value in t_attrs.items():
        #         if value or isinstance(value, string_types)):
        #             append(u' ')
        #             append(name)
        #             append(u'="')
        #             append(escape(pycompat.to_text((value)))
        #             append(u'"')
        #
        #     if not content and tagName in self._void_elements:
        #         append('/>')
        #     else:
        #         append('>')
        #         if content:
        #           append(content)
        #         append('</')
        #         append(tagName)
        #         append('>')
        #
        space = el.getprevious() is not None and el.getprevious().tail or el.getparent().text
        sep = u'\n' + space.rsplit('\n').pop()
        return [
            ast.Assign(
                targets=[ast.Name(id='nodes', ctx=ast.Store())],
                value=ast.Call(
                    func=ast.Attribute(
                        value=ast.Name(id='self', ctx=ast.Load()),
                        attr='_get_asset_nodes',
                        ctx=ast.Load()
                    ),
                    args=[
                        ast.Str(el.get('t-call-assets')),
                        ast.Name(id='options', ctx=ast.Load()),
                    ],
                    keywords=[
                        ast.keyword('css', self._get_attr_bool(el.get('t-css', True))),
                        ast.keyword('js', self._get_attr_bool(el.get('t-js', True))),
                        ast.keyword('debug', ast.Call(
                            func=ast.Attribute(
                                value=ast.Name(id='values', ctx=ast.Load()),
                                attr='get',
                                ctx=ast.Load()
                            ),
                            args=[ast.Str('debug')],
                            keywords=[], starargs=None, kwargs=None
                        )),
                        ast.keyword('async_load', self._get_attr_bool(el.get('async_load', False))),
                        ast.keyword('defer_load', self._get_attr_bool(el.get('defer_load', False))),
                        ast.keyword('lazy_load', self._get_attr_bool(el.get('lazy_load', False))),
                        ast.keyword('values', ast.Name(id='values', ctx=ast.Load())),
                    ],
                    starargs=None, kwargs=None
                )
            ),
            ast.For(
                target=ast.Tuple(elts=[
                    ast.Name(id='index', ctx=ast.Store()),
                    ast.Tuple(elts=[
                        ast.Name(id='tagName', ctx=ast.Store()),
                        ast.Name(id='t_attrs', ctx=ast.Store()),
                        ast.Name(id='content', ctx=ast.Store())
                    ], ctx=ast.Store())
                ], ctx=ast.Store()),
                iter=ast.Call(
                    func=ast.Name(id='enumerate', ctx=ast.Load()),
                    args=[ast.Name(id='nodes', ctx=ast.Load())],
                    keywords=[],
                    starargs=None, kwargs=None
                ),
                body=[
                    ast.If(
                        test=ast.Name(id='index', ctx=ast.Load()),
                        body=[self._append(ast.Str(sep))],
                        orelse=[]
                    ),
                    self._append(ast.Str(u'<')),
                    self._append(ast.Name(id='tagName', ctx=ast.Load())),
                ] + self._append_attributes() + [
                    ast.If(
                        test=ast.BoolOp(
                            op=ast.And(),
                            values=[
                                ast.UnaryOp(ast.Not(), ast.Name(id='content', ctx=ast.Load()), lineno=0, col_offset=0),
                                ast.Compare(
                                    left=ast.Name(id='tagName', ctx=ast.Load()),
                                    ops=[ast.In()],
                                    comparators=[ast.Attribute(
                                        value=ast.Name(id='self', ctx=ast.Load()),
                                        attr='_void_elements',
                                        ctx=ast.Load()
                                    )]
                                ),
                            ]
                        ),
                        body=[self._append(ast.Str(u'/>'))],
                        orelse=[
                            self._append(ast.Str(u'>')),
                            ast.If(
                                test=ast.Name(id='content', ctx=ast.Load()),
                                body=[self._append(ast.Name(id='content', ctx=ast.Load()))],
                                orelse=[]
                            ),
                            self._append(ast.Str(u'</')),
                            self._append(ast.Name(id='tagName', ctx=ast.Load())),
                            self._append(ast.Str(u'>')),
                        ]
                    )
                ],
                orelse=[]
            )
        ]
Esempio n. 49
0
def compile_ui_files(module, import_instructions=None):
    """
    Reads recursively all *.py files in root directory looking for
    "generate_pyfile_from_uifile" calls.
    If this call is found, execute it in order to compile ui file.

    import_instructions : python code containing required imports.
    example :

    >>> import_instructions = 'from openalea.vpltk.qt.designer import generate_pyfile_from_uifile\n'

    if None, uses default imports : generate_pyfile_from_uifile, Path, hardbook and get_data
    """
    import ast
    from openalea.core import codegen

    if import_instructions is None:
        import_instructions = "from openalea.vpltk.qt.designer import generate_pyfile_from_uifile\n"

    module = __import__(module)
    paths = []
    for root in module.__path__:
        root = Path(root)
        for py in root.walkfiles('*.py'):
            paths.append((root, py))

    for root, py in paths:
        f = open(py)
        lines = f.readlines()
        f.close()

        code = ''.join(lines)
        try:
            r = ast.parse(code)
        except SyntaxError:
            print 'SYNTAX ERROR: cannot read ...', py
        else:
            for instr in r.body:
                if isinstance(instr, ast.Expr):
                    value = instr.value
                    if isinstance(value, ast.Call):
                        try:
                            func_name = value.func.id
                        except AttributeError:
                            pass
                        else:
                            if func_name == 'generate_pyfile_from_uifile':
                                true = ast.parse('True').body[0]

                                for keyword in value.keywords:
                                    if keyword.arg == 'force':
                                        keyword.value = true
                                        break
                                else:
                                    value.keywords.append(ast.keyword('force', true))
                                src = codegen.to_source(instr)

                                if py.startswith('./') or py.startswith('.\\'):
                                    py = Path(py[2:])
                                name = replaceext(root.parent.relpathto(py), '').replace(os.sep, '.')
                                src = src.replace('__name__', repr(name))
                                try:
                                    code = compile(import_instructions + src, "<string>", "exec")
                                    exec code
                                except Exception as e:
                                    print repr(e)
                                    print 'COMPILATION ERROR: cannot compile', py
                                    print
Esempio n. 50
0
 def keyword(arg, value):
     return _ast.keyword(str(arg), value)
Esempio n. 51
0
def ast_default_field(value):
    return Call(
        func=Name(id='field', ctx=Load()),
        args=[],
        keywords=[keyword(arg='default', value=Constant(value=value, kind=None))]
    )
Esempio n. 52
0
    def visit_Call(self, node):  # pylint: disable=invalid-name
        self.generic_visit(node)

        # ignore if the function is not 'nni.*'
        if type(node.func) is not ast.Attribute:
            return node
        if type(node.func.value) is not ast.Name:
            return node
        if node.func.value.id != 'nni':
            return node

        # ignore if its not a search space function (e.g. `report_final_result`)
        func = node.func.attr
        if func not in _ss_funcs:
            return node

        self.last_line = node.lineno

        if node.keywords:
            # there is a `name` argument
            assert len(
                node.keywords
            ) == 1, 'Smart parameter has keyword argument other than "name"'
            assert node.keywords[
                0].arg == 'name', 'Smart paramater\'s keyword argument is not "name"'
            assert type(
                node.keywords[0].value
            ) is ast.Str, 'Smart parameter\'s name must be string literal'
            name = node.keywords[0].value.s
            specified_name = True
        else:
            # generate the missing name automatically
            name = '__line' + str(str(node.args[-1].lineno))
            specified_name = False
            node.keywords = list()

        if func in ('choice', 'function_choice'):
            # we will use keys in the dict as the choices, which is generated by code_generator according to the args given by user
            assert len(node.args
                       ) == 1, 'Smart parameter has arguments other than dict'
            # check if it is a number or a string and get its value accordingly
            args = [
                key.n if type(key) is ast.Num else key.s
                for key in node.args[0].keys
            ]
        else:
            # arguments of other functions must be literal number
            assert all(
                type(arg) is ast.Num for arg in node.args
            ), 'Smart parameter\'s arguments must be number literals'
            args = [arg.n for arg in node.args]

        key = self.module_name + '/' + name + '/' + func
        # store key in ast.Call
        node.keywords.append(ast.keyword(arg='key', value=ast.Str(s=key)))

        if func == 'function_choice':
            func = 'choice'
        value = {'_type': func, '_value': args}

        if specified_name:
            # multiple functions with same name must have identical arguments
            old = self.search_space.get(key)
            assert old is None or old == value, 'Different smart parameters have same name'
        else:
            # generated name must not duplicate
            assert key not in self.search_space, 'Only one smart parameter is allowed in a line'

        self.search_space[key] = value

        return node
Esempio n. 53
0
    def visit_BinOp(self, node):
        if node.op.__class__ in self.operators:
            sympy_class = self.operators[node.op.__class__]
            right = self.visit(node.right)
            left = self.visit(node.left)
            if isinstance(node.left, ast.UnaryOp) and (isinstance(
                    node.right,
                    ast.UnaryOp) == 0) and sympy_class in ('Mul', ):
                left, right = right, left
            if isinstance(node.op, ast.Sub):
                right = ast.Call(func=ast.Name(id='Mul', ctx=ast.Load()),
                                 args=[
                                     ast.UnaryOp(op=ast.USub(),
                                                 operand=ast.Num(1)), right
                                 ],
                                 keywords=[
                                     ast.keyword(arg='evaluate',
                                                 value=ast.NameConstant(
                                                     value=False,
                                                     ctx=ast.Load()))
                                 ],
                                 starargs=None,
                                 kwargs=None)
            if isinstance(node.op, ast.Div):
                if isinstance(node.left, ast.UnaryOp):
                    if isinstance(node.right, ast.UnaryOp):
                        left, right = right, left
                    left = ast.Call(func=ast.Name(id='Pow', ctx=ast.Load()),
                                    args=[
                                        left,
                                        ast.UnaryOp(op=ast.USub(),
                                                    operand=ast.Num(1))
                                    ],
                                    keywords=[
                                        ast.keyword(arg='evaluate',
                                                    value=ast.NameConstant(
                                                        value=False,
                                                        ctx=ast.Load()))
                                    ],
                                    starargs=None,
                                    kwargs=None)
                else:
                    right = ast.Call(func=ast.Name(id='Pow', ctx=ast.Load()),
                                     args=[
                                         right,
                                         ast.UnaryOp(op=ast.USub(),
                                                     operand=ast.Num(1))
                                     ],
                                     keywords=[
                                         ast.keyword(arg='evaluate',
                                                     value=ast.NameConstant(
                                                         value=False,
                                                         ctx=ast.Load()))
                                     ],
                                     starargs=None,
                                     kwargs=None)

            new_node = ast.Call(func=ast.Name(id=sympy_class, ctx=ast.Load()),
                                args=[left, right],
                                keywords=[
                                    ast.keyword(arg='evaluate',
                                                value=ast.NameConstant(
                                                    value=False,
                                                    ctx=ast.Load()))
                                ],
                                starargs=None,
                                kwargs=None)

            if sympy_class in ('Add', 'Mul'):
                # Denest Add or Mul as appropriate
                new_node.args = self.flatten(new_node.args, sympy_class)

            return new_node
        return node
Esempio n. 54
0
async def meval(code, **kwargs):
    # Don't clutter locals
    locs = {}
    # Restore globals later
    globs = globals().copy()
    # This code saves __name__ and __package into a kwarg passed to the function.
    # It is set before the users code runs to make sure relative imports work
    global_args = "_globs"
    while global_args in globs.keys():
        # Make sure there's no name collision, just keep prepending _s
        global_args = "_" + global_args
    kwargs[global_args] = {}
    for glob in ["__name__", "__package__"]:
        # Copy data to args we are sending
        kwargs[global_args][glob] = globs[glob]

    root = ast.parse(code, "exec")
    code = root.body
    if isinstance(
            code[-1],
            ast.Expr):  # If we can use it as a lambda return (but multiline)
        code[-1] = ast.copy_location(ast.Return(
            code[-1].value), code[-1])  # Change it to a return statement
    # globals().update(**<global_args>)
    glob_copy = ast.Expr(
        ast.Call(
            func=ast.Attribute(value=ast.Call(func=ast.Name(id="globals",
                                                            ctx=ast.Load()),
                                              args=[],
                                              keywords=[]),
                               attr="update",
                               ctx=ast.Load()),
            args=[],
            keywords=[
                ast.keyword(arg=None,
                            value=ast.Name(id=global_args, ctx=ast.Load()))
            ]))
    ast.fix_missing_locations(glob_copy)
    code.insert(0, glob_copy)
    args = []
    for a in list(map(lambda x: ast.arg(x, None), kwargs.keys())):
        ast.fix_missing_locations(a)
        args += [a]
    args = ast.arguments(args=[],
                         vararg=None,
                         kwonlyargs=args,
                         kwarg=None,
                         defaults=[],
                         kw_defaults=[None for i in range(len(args))])
    if int.from_bytes(importlib.util.MAGIC_NUMBER[:-2], 'little') >= 3410:
        args.posonlyargs = []
    fun = ast.AsyncFunctionDef(name="tmp",
                               args=args,
                               body=code,
                               decorator_list=[],
                               returns=None)
    ast.fix_missing_locations(fun)
    mod = ast.parse("")
    mod.body = [fun]
    comp = compile(mod, "<string>", "exec")

    exec(comp, {}, locs)

    r = await locs["tmp"](**kwargs)

    if isinstance(r, types.CoroutineType) or isinstance(r, _asyncio.Future):
        r = await r  # workaround for 3.5
    try:
        globals().clear()
        # Inconsistent state
    finally:
        globals().update(**globs)
    return r
Esempio n. 55
0
    def transform(tree, *, forcing_mode, stop, **kw):
        def rec(tree,
                forcing_mode=forcing_mode
                ):  # shorthand that defaults to current mode
            return transform.recurse(tree, forcing_mode=forcing_mode)

        # Forcing references (Name, Attribute, Subscript):
        #   x -> f(x)
        #   a.x -> f(force1(a).x)
        #   a.b.x -> f(force1(force1(a).b).x)
        #   a[j] -> f((force1(a))[force(j)])
        #   a[j][k] -> f(force1(force1(a)[force(j)])[force(k)])
        #
        # where f is force, force1 or identity (optimized away) depending on
        # where the term appears; j and k may be indices or slices.
        #
        # Whenever not in Load context, f is identity.
        #
        # The idea is to apply just the right level of forcing to be able to
        # resolve the reference, and then decide what to do with the resolved
        # reference based on where it appears.
        #
        # For example, when subscripting a list, force1 it to unwrap it from
        # a promise if it happens to be inside one, but don't force its elements
        # just for the sake of resolving the reference. Then, apply f to the
        # whole subscript term (forcing the accessed slice of the list, if necessary).
        def f(tree):
            if type(tree.ctx) is Load:
                if forcing_mode == "full":
                    return hq[force(ast_literal[tree])]
                elif forcing_mode == "flat":
                    return hq[force1(ast_literal[tree])]
                # else forcing_mode == "off"
            return tree

        if type(tree) in (FunctionDef, AsyncFunctionDef, Lambda):
            if type(tree) is Lambda and id(tree) not in userlambdas:
                pass  # ignore macro-introduced lambdas
            else:
                stop()

                # mark this definition as lazy, and insert the interface wrapper
                # to allow also strict code to call this function
                if type(tree) is Lambda:
                    lam = tree
                    tree = hq[mark_lazy(ast_literal[tree])]
                    tree = sort_lambda_decorators(tree)
                    lam.body = rec(lam.body)
                else:
                    tree.decorator_list = rec(tree.decorator_list)
                    k = suggest_decorator_index("mark_lazy",
                                                tree.decorator_list)
                    if k is not None:
                        tree.decorator_list.insert(k, hq[mark_lazy])
                    else:
                        # mark_lazy should generally be as innermost as possible
                        # (so that e.g. the curry decorator will see the function as lazy)
                        tree.decorator_list.append(hq[mark_lazy])
                    tree.body = rec(tree.body)

        elif type(tree) is Call:

            def transform_arg(tree):
                # add any needed force() invocations inside the tree,
                # but leave the top level of simple references untouched.
                isref = type(tree) in (Name, Attribute, Subscript)
                tree = rec(tree, forcing_mode=("off" if isref else "full"))
                if not isref:  # (re-)thunkify expr; a reference can be passed as-is.
                    tree = lazyrec(tree)
                return tree

            def transform_starred(tree, dstarred=False):
                isref = type(tree) in (Name, Attribute, Subscript)
                tree = rec(tree, forcing_mode=("off" if isref else "full"))
                # lazify items if we have a literal container
                # we must avoid lazifying any other exprs, since a Lazy cannot be unpacked.
                if is_literal_container(tree, maps_only=dstarred):
                    tree = lazyrec(tree)
                return tree

            # let bindings have a role similar to function arguments, so auto-lazify there
            # (LHSs are always new names, so no infinite loop trap for the unwary)
            if islet(tree):
                stop()
                view = ExpandedLetView(tree)
                if view.mode == "let":
                    for b in view.bindings.elts:  # b = (name, value)
                        b.elts[1] = transform_arg(b.elts[1])
                else:  # view.mode == "letrec":
                    for b in view.bindings.elts:  # b = (name, (lambda e: ...))
                        thelambda = b.elts[1]
                        thelambda.body = transform_arg(thelambda.body)
                if view.body:  # let decorators have no body inside the Call node
                    thelambda = view.body
                    thelambda.body = rec(thelambda.body)
            # namelambda() is used by let[] and do[]
            # Lazy() is a strict function, takes a lambda, constructs a Lazy object
            # _autoref_resolve doesn't need any special handling
            elif isdo(tree) or is_decorator(tree.func, "namelambda") or \
               any(isx(tree.func, s) for s in _ctorcalls_all) or isx(tree.func, isLazy) or \
               any(isx(tree.func, s) for s in ("_autoref_resolve", "AutorefMarker")):
                # here we know the operator (.func) to be one of specific names;
                # don't transform it to avoid confusing lazyrec[] (important if this
                # is an inner call in the arglist of an outer, lazy call, since it
                # must see any container constructor calls that appear in the args)
                stop()
                # TODO: correct forcing mode? We shouldn't need to forcibly use "full",
                # since lazycall() already fully forces any remaining promises
                # in the args when calling a strict function.
                tree.args = rec(tree.args)
                tree.keywords = rec(tree.keywords)
                # Python 3.4
                if hasattr(tree, "starargs"):
                    tree.starargs = rec(tree.starargs)
                if hasattr(tree, "kwargs"): tree.kwargs = rec(tree.kwargs)
            else:
                stop()
                ln, co = tree.lineno, tree.col_offset
                thefunc = rec(tree.func)

                # TODO: test *args support in Python 3.5+ (this **should** work according to the AST specs)
                adata = []
                for x in tree.args:
                    if type(x) is Starred:  # *args in Python 3.5+
                        v = transform_starred(x.value)
                        v = Starred(value=q[ast_literal[v]],
                                    lineno=ln,
                                    col_offset=co)
                    else:
                        v = transform_arg(x)
                    adata.append(v)

                # TODO: test **kwargs support in Python 3.5+ (this **should** work according to the AST specs)
                kwdata = []
                for x in tree.keywords:
                    if x.arg is None:  # **kwargs in Python 3.5+
                        v = transform_starred(x.value, dstarred=True)
                    else:
                        v = transform_arg(x.value)
                    kwdata.append((x.arg, v))

                # Construct the call
                mycall = Call(func=hq[lazycall],
                              args=[q[ast_literal[thefunc]]] +
                              [q[ast_literal[x]] for x in adata],
                              keywords=[
                                  keyword(arg=k, value=q[ast_literal[x]])
                                  for k, x in kwdata
                              ],
                              lineno=ln,
                              col_offset=co)

                if hasattr(tree, "starargs"):  # *args in Python 3.4
                    if tree.starargs is not None:
                        mycall.starargs = transform_starred(tree.starargs)
                    else:
                        mycall.starargs = None
                if hasattr(tree, "kwargs"):  # **kwargs in Python 3.4
                    if tree.kwargs is not None:
                        mycall.kwargs = transform_starred(tree.kwargs,
                                                          dstarred=True)
                    else:
                        mycall.kwargs = None

                tree = mycall

        elif type(tree) is Subscript:  # force only accessed part of obj[...]
            stop()
            tree.slice = rec(tree.slice, forcing_mode="full")
            # resolve reference to the actual container without forcing its items.
            tree.value = rec(tree.value, forcing_mode="flat")
            tree = f(tree)

        elif type(tree) is Attribute:
            #   a.b.c --> f(force1(force1(a).b).c)  (Load)
            #         -->   force1(force1(a).b).c   (Store)
            #   attr="c", value=a.b
            #   attr="b", value=a
            # Note in case of assignment to a compound, only the outermost
            # Attribute is in Store context.
            #
            # Recurse in flat mode. Consider lst = [[1, 2], 3]
            #   lst[0] --> f(force1(lst)[0]), but
            #   lst[0].append --> force1(force1(force1(lst)[0]).append)
            # Hence, looking up an attribute should only force **the object**
            # so that we can perform the attribute lookup on it, whereas
            # looking up values should finally f() the whole slice.
            # (In the above examples, we have omitted f() when it is identity;
            #  in reality there is always an f() around the whole expr.)
            stop()
            tree.value = rec(tree.value, forcing_mode="flat")
            tree = f(tree)

        elif type(tree) is Name and type(tree.ctx) is Load:
            stop()  # must not recurse when a Name changes into a Call.
            tree = f(tree)

        return tree
    def handleNode(self, node, parent, scope):
        # Scope variables
        if isinstance(node, ast.Name) and not isinstance(node.ctx, ast.Param):
            return ast.Subscript(
                value=ast.Name(id="scope%s" % scope, ctx=ast.Load()),
                slice=ast.Index(value=ast.Str(s=node.id)),
                ctx=node.ctx
            )

        # Global
        if isinstance(node, ast.Global):
            res = []
            for name in node.names:
                res.append(ast.Expr(value=ast.Call(
                    func=ast.Attribute(
                        value=ast.Name(id="scope%s" % scope, ctx=ast.Load()),
                        attr="inheritVariable",
                        ctx=ast.Load()
                    ),
                    args=[
                        ast.Name(id="scope0", ctx=ast.Load()),
                        ast.Str(s=name)
                    ],
                    keywords=[], starargs=None, kwargs=None
                )))
            return res

        # Import
        if isinstance(node, ast.Import) or isinstance(node, ast.ImportFrom):
            none = ast.Name(id="None", ctx=ast.Load())

            names = ast.List(elts=[
                ast.Tuple(elts=[
                    ast.Str(s=name.name),
                    ast.Str(s=name.asname) if name.asname else none
                ], ctx=ast.Load())
                for name in node.names
            ], ctx=ast.Load())

            if isinstance(node, ast.ImportFrom):
                from_ = ast.Str(node.module) if node.module else none
                level = ast.Num(node.level or 0)
            else:
                from_ = none
                level = none

            return ast.Expr(value=ast.Call(
                func=ast.Attribute(
                    value=ast.Name(id="scope%s" % scope, ctx=ast.Load()),
                    attr="import_",
                    ctx=ast.Load()
                ),
                args=[names, from_, level],
                keywords=[], starargs=None, kwargs=None
            ))


        if isinstance(node, ast.FunctionDef):
            scope += 1

        if isinstance(node, ast.Lambda):
            # Handle arguments (default values) in parent scope
            args = self.handleNode(node.args, node, scope)
            if args is not None:
                node.args = args

            # Now increment scope and handle body
            scope += 1
            body = self.handleNode(node.body, node, scope)
            if body is not None:
                node.body = body
        else:
            for fieldname, value in ast.iter_fields(node):
                if isinstance(value, ast.AST):
                    res = self.handleNode(value, node, scope)
                    if res is not None:
                        setattr(node, fieldname, res)
                elif isinstance(value, list):
                    result = []
                    for child in value:
                        val = self.handleNode(child, node, scope)
                        if val is None:
                            result.append(child)
                        elif isinstance(val, list):
                            result += val
                        else:
                            result.append(val)
                    setattr(node, fieldname, result)

        # Add scope to functions
        if isinstance(node, ast.FunctionDef):
            node.body.insert(0, ast.Assign(
                targets=[ast.Name(id="scope%s" % scope, ctx=ast.Store())],
                value=ast.Call(
                    func=ast.Attribute(
                        value=ast.Name(id="scope%s" % (scope-1), ctx=ast.Load()),
                        attr="inherit",
                        ctx=ast.Load()
                    ),
                    args=[], keywords=[],
                    starargs=None, kwargs=None
                )
            ))

            # Arguments
            for arg in node.args.args:
                node.body.insert(1, ast.Assign(
                    targets=[ast.Subscript(
                        value=ast.Name(id="scope%s" % scope, ctx=ast.Load()),
                        slice=ast.Index(value=ast.Str(s=arg.id)),
                        ctx=ast.Store()
                    )],
                    value=ast.Name(id=arg.id, ctx=ast.Load())
                ))

            # Vararg
            if node.args.vararg is not None:
                node.body.insert(1, ast.Assign(
                    targets=[ast.Subscript(
                        value=ast.Name(id="scope%s" % scope, ctx=ast.Load()),
                        slice=ast.Index(value=ast.Str(s=node.args.vararg)),
                        ctx=ast.Store()
                    )],
                    value=ast.Name(id=node.args.vararg, ctx=ast.Load())
                ))

            # Kwarg
            if node.args.kwarg is not None:
                node.body.insert(1, ast.Assign(
                    targets=[ast.Subscript(
                        value=ast.Name(id="scope%s" % scope, ctx=ast.Load()),
                        slice=ast.Index(value=ast.Str(s=node.args.kwarg)),
                        ctx=ast.Store()
                    )],
                    value=ast.Name(id=node.args.kwarg, ctx=ast.Load())
                ))

        # Save functions (not methods) to scope
        if isinstance(node, ast.FunctionDef) and not isinstance(parent, ast.ClassDef):
            oldname = node.name
            node.name = "_user_%s_%s_" % (oldname, scope)

            return [
                node,
                ast.Assign(
                    targets=[ast.Subscript(
                        value=ast.Name(id="scope%s" % (scope-1), ctx=ast.Load()),
                        slice=ast.Index(value=ast.Str(s=oldname)),
                        ctx=ast.Store()
                    )],
                    value=ast.Name(id=node.name, ctx=ast.Load())
                )
            ]

        # Save classes to scope
        if isinstance(node, ast.ClassDef) and not isinstance(parent, ast.ClassDef):
            oldname = node.name
            node.name = "_user_%s_%s_" % (oldname, scope)

            return [
                node,
                ast.Assign(
                    targets=[ast.Subscript(
                        value=ast.Name(id="scope%s" % scope, ctx=ast.Load()),
                        slice=ast.Index(value=ast.Str(s=oldname)),
                        ctx=ast.Store()
                    )],
                    value=ast.Name(id=node.name, ctx=ast.Load())
                )
            ]

        # Print
        if isinstance(node, ast.Print):
            true = ast.Name(id="True", ctx=ast.Load())
            false = ast.Name(id="False", ctx=ast.Load())
            none = ast.Name(id="None", ctx=ast.Load())

            return ast.Expr(value=ast.Call(
                func=ast.Subscript(
                    value=ast.Attribute(
                        value=ast.Name(id="scope0", ctx=ast.Load()),
                        attr="inherits",
                        ctx=ast.Load()
                    ),
                    slice=ast.Index(value=ast.Str(s="print")),
                    ctx=ast.Load()
                ),
                args=node.values, keywords=[
                    ast.keyword(arg="nl", value=true if node.nl else false),
                    ast.keyword(arg="dest", value=node.dest or none)
                ],
                starargs=None, kwargs=None
            ))

        # Add scope to lambdas
        if isinstance(node, ast.Lambda):
            # lambda a: a
            # ->
            # lambda a: (lambda scope1: scope1["a"])(scope0.extend({"a": a}))

            # We save everything to dict, don't assign automatically
            dct = ast.Dict(keys=[], values=[])

            # Arguments
            for arg in node.args.args:
                dct.keys.append(ast.Str(s=arg.id))
                dct.values.append(ast.Name(id=arg.id, ctx=ast.Load()))

            # Vararg
            if node.args.vararg is not None:
                dct.keys.append(ast.Str(s=node.args.vararg))
                dct.values.append(ast.Name(id=node.args.vararg, ctx=ast.Load()))

            # Kwarg
            if node.args.kwarg is not None:
                dct.keys.append(ast.Str(s=node.args.kwarg))
                dct.values.append(ast.Name(id=node.args.kwarg, ctx=ast.Load()))

            node.body = ast.Call(
                func=ast.Lambda(
                    args=ast.arguments(
                        args=[ast.Name(id="scope%s" % scope, ctx=ast.Load())],
                        vararg=None, kwarg=None, defaults=[]
                    ),
                    body=node.body
                ),
                args=[
                    ast.Call(
                        func=ast.Attribute(
                            value=ast.Name(id="scope%s" % (scope - 1), ctx=ast.Load()),
                            attr="extend",
                            ctx=ast.Load()
                        ),
                        args=[dct], keywords=[],
                        starargs=None, kwargs=None
                    )
                ],
                keywords=[], starargs=None, kwargs=None
            )

        # Now do something to prevent object.__subclasses__() hacks and others
        if (
            isinstance(node, ast.Attribute) and
            ((
                node.attr.startswith("__") and
                node.attr.endswith("__")
            ) or (
                node.attr.startswith("func_")
            ))
        ):
            return ast.Subscript(
                value=ast.Call(
                    func=ast.Attribute(
                        value=ast.Name(id="scope0", ctx=ast.Load()),
                        attr="safeAttr",
                        ctx=ast.Load()
                    ),
                    args=[node.value],
                    keywords=[], starargs=None, kwargs=None
                ),
                slice=ast.Index(value=ast.Str(node.attr)),
                ctx=node.ctx
            )
Esempio n. 57
0
    def visit_FunctionDef(self, node):
        """ Instrument a function definition by creating a new report builder
        for this stack frame and putting it in a local variable. The local
        variable has the same name as the global variable so all calls can
        use the same CONTEXT_NAME symbol, but it means that I had to use this:
        x = globals()['x'].start_frame()
        Kind of ugly, but I think it was worth it to handle recursive calls.
        """
        new_node = self.generic_visit(node)

        line_numbers = set()
        find_line_numbers(new_node, line_numbers)
        first_line_number = min(line_numbers)
        last_line_number = max(line_numbers)
        args = [Num(n=first_line_number),
                Num(n=last_line_number)]
        start_frame_keywords = []
        for decorator in new_node.decorator_list:
            if getattr(decorator, 'id', None) == 'traced':
                start_frame_keywords.append(
                    keyword(arg='is_decorated', value=Name(id='True',
                                                           ctx=Load())))
        try_body = new_node.body
        globals_call = Call(func=Name(id='globals', ctx=Load()),
                            args=[],
                            keywords=[],
                            starargs=None,
                            kwargs=None)
        global_context = Subscript(value=globals_call,
                                   slice=Index(value=Str(s=CONTEXT_NAME)),
                                   ctx=Load())
        start_frame_call = Call(func=Attribute(value=global_context,
                                               attr='start_frame',
                                               ctx=Load()),
                                args=args,
                                keywords=start_frame_keywords,
                                starargs=None,
                                kwargs=None)
        context_assign = Assign(targets=[Name(id=CONTEXT_NAME, ctx=Store())],
                                value=start_frame_call)
        new_node.body = [context_assign]
        if isinstance(try_body[0], Expr) and isinstance(try_body[0].value, Str):
            # Move docstring back to top of function.
            # noinspection PyUnresolvedReferences
            new_node.body.insert(0, try_body.pop(0))

        # trace function parameter values
        for target in new_node.args.args:
            if isinstance(target, Name) and target.id == 'self':
                continue
            if arg and isinstance(target, arg) and target.arg == 'self':
                continue
            new_node.body.append(self._trace_assignment(target, node.lineno))
        if new_node.args.vararg is not None:
            new_node.body.append(
                self._trace_assignment(new_node.args.vararg, node.lineno))
        if new_node.args.kwarg is not None:
            new_node.body.append(
                self._trace_assignment(new_node.args.kwarg, node.lineno))

        if try_body:
            handler_body = [self._create_context_call('exception'),
                            Raise()]
            new_node.body.append(
                TryExcept(body=try_body,
                          handlers=[ExceptHandler(body=handler_body)],
                          orelse=[],
                          finalbody=[]))
            self._set_statement_line_numbers(try_body, first_line_number)
            self._set_statement_line_numbers(handler_body, last_line_number)
        return new_node
Esempio n. 58
0
 def add_kwarg_to_super_call(super_call, kwarg):
     super_call.value.keywords.append(
         ast.keyword(arg=None, value=ast.Name(id=kwarg.arg,
                                              ctx=ast.Load())))
Esempio n. 59
0
def ast_list(tree):
    """Splices a list of ASTs into the quoted code snippet as a List node."""
    return Literal(compat.Call(ast.Attribute(
        value=ast.Name(id='ast', ctx=ast.Load()),
        attr='List', ctx=ast.Load()), [], [ast.keyword("elts", tree)]))
Esempio n. 60
0
                     ],
                     func=Attribute(
                         Name("math_ops", Load()),
                         "square",
                         Load(),
                     ),
                     keywords=[],
                     expr=None,
                     expr_func=None,
                 )
             ],
             func=Attribute(Name("K", Load()), "mean", Load()),
             keywords=[
                 keyword(
                     arg="axis",
                     value=UnaryOp(USub(), set_value(1)),
                     identifier=None,
                 )
             ],
             expr=None,
             expr_func=None,
         ),
         expr=None,
     ),
 ],
 decorator_list=[],
 name="__call__",
 returns=None,
 arguments_args=None,
 identifier_name=None,
 stmt=None,