Example #1
0
def test_ast_tree_edit_distance() -> None:
    node1 = ast.parse("a=1")
    node2 = ast.parse("a=1")
    assert ast_tree_edit_distance(node1, node2) == 0
    node2 = ast.parse("b=1")
    assert ast_tree_edit_distance(node1, node2) == 1
    node2 = ast.parse("b=2")
    assert ast_tree_edit_distance(node1, node2) == 1.5
    node1 = Assign(
        targets=[Name(id="a", ctx=Store())],
        value=Constant(value=1, kind=None),
        type_comment=None,
    )
    node2 = Assign(
        targets=[Name(id="a", ctx=Store())],
        value=Constant(value=1, kind=None),
        type_comment=None,
    )
    assert ast_tree_edit_distance(node1, node2) == 0
    node1 = ast.parse("")
    node2 = ast.parse("")
    assert ast_tree_edit_distance(node1, node2) == 0
    node1 = ast.parse("a")
    node2 = ast.parse("a")
    assert ast_tree_edit_distance(node1, node2) == 0
    node1 = Expr(Name("a", Load()))
    node2 = Expr(Name("a", Load()))
    assert ast_tree_edit_distance(node1, node2) == 0
    node1 = Name("a", Load())
    node2 = Name("a", Load())
    assert ast_tree_edit_distance(node1, node2) == 0
Example #2
0
def blocks(it, lvl=0):
  cur = lvl
  expr = Expr()
  blk = Block(expr)
  prefix = str(lvl)+" "*(lvl-1)
  for t in it:
    log.indent(prefix, "considering", t)
    if isinstance(t, DENT):
      cur = t.value
      if cur == lvl and expr:
        log.indent(prefix, "got newline, starting new expr")
        expr = Expr()
        blk.append(expr)
        continue
      elif cur > lvl:
        log.indent(prefix, ">>> calling nested block")
        r, cur = blocks(it, cur)
        log.indent(prefix, "<<< got %s from it with level %s" % (r, cur))
        expr.append(r)
        if cur == lvl:
          log.indent(prefix, "!!! starting new expression")
          expr = Expr()
          blk.append(expr)
    else:
      log.indent(prefix, "adding %s to expr %s" % (t,expr))
      expr.append(t)
    if cur < lvl:
        log.indent(prefix, "<== %s < %s: time to return" % (cur, lvl))
        return blk, cur
  return blk, lvl
Example #3
0
    def expr(self):
        self.dbg_msg(" EXPR ")
        val1 = self.term()
        res = val1
        ptok = self.peek()
        if ptok.kind in EzhilToken.ADDSUB:
            binop = self.dequeue()
            if (ptok.kind == EzhilToken.MINUS):
                val2 = self.term()
            else:
                val2 = self.expr()
            [l, c] = binop.get_line_col()
            res = Expr(val1, binop, val2, l, c, self.debug)
        elif ptok.kind == EzhilToken.LPAREN:
            ## function call
            if (res.__class__ != Identifier):
                raise ParseException("invalid function call" + str(ptok))
            [l, c] = ptok.get_line_col()
            vallist = self.valuelist()
            res = ExprCall(res, vallist, l, c, self.debug)

        ptok = self.peek()
        while ptok.kind in EzhilToken.BINOP:
            binop = self.dequeue()
            [l, c] = binop.get_line_col()
            res = Expr(res, binop, self.expr(), l, c, self.debug)
            ptok = self.peek()
        return res
def _convertExprStmt2Expression(expr_stmt:ast.Expr)->Any:
    expr_stmt = copy.deepcopy(expr_stmt)
    expr_stmt.lineno = 0
    expr_stmt.col_offset = 0

    expr_stmt_value = expr_stmt.value

    stmt_expression = ast.Expression(expr_stmt_value, lineno=0, col_offset=0)
    return stmt_expression
Example #5
0
 def visit_Expr(self, node):
     """Handle visiting an expression."""
     if self.is_in_scope(node):
         return node
     else:
         newnode = self.try_subproc_toks(node)
         if not isinstance(newnode, Expr):
             newnode = Expr(value=newnode,
                            lineno=node.lineno,
                            col_offset=node.col_offset)
             if hasattr(node, 'max_lineno'):
                 newnode.max_lineno = node.max_lineno
                 newnode.max_col = node.max_col
         return newnode
Example #6
0
 def test_param2argparse_param_default_ast_expr_with_list(self) -> None:
     """
     Tests that param2argparse_param works to change the type based on the default
       whence said default is an ast.List inside an ast.Expr
     """
     run_ast_test(
         gen_ast=param2argparse_param(
             (
                 "byo",
                 {
                     "default": Expr(
                         List(
                             elts=[],
                             ctx=Load(),
                             expr=None,
                         ),
                         expr_value=None,
                     ),
                     "typ": "str",
                 },
             ),
         ),
         gold=argparse_add_argument_expr,
         test_case_instance=self,
     )
Example #7
0
 def test_param2argparse_param_default_simple_type(self) -> None:
     """
     Tests that param2argparse_param works to change the type based on the default
     """
     run_ast_test(
         gen_ast=param2argparse_param(
             ("byo", {"default": 5, "typ": "str"}),
         ),
         gold=Expr(
             Call(
                 args=[set_value("--byo")],
                 func=Attribute(
                     Name("argument_parser", Load()),
                     "add_argument",
                     Load(),
                 ),
                 keywords=[
                     keyword(arg="type", value=Name("int", Load()), identifier=None),
                     keyword(arg="required", value=set_value(True), identifier=None),
                     keyword(arg="default", value=set_value(5), identifier=None),
                 ],
                 expr=None,
                 expr_func=None,
             )
         ),
         test_case_instance=self,
     )
    def visit_Module(self, node):
        logging.info("Adding " + str(len(self.globalvars)) +
                     " global variables, " + str(len(self.methods)) + " methods")
        node_body = node.body
        node.body = []
        for n in node_body:
            if type(n) is ast.ImportFrom or type(n) is ast.Import:
                node.body.append(n)
                node_body.remove(n)

        node.body.append(
            Import(names=[alias(name='sys', asname=None)])
        )
        node.body.append(Expr(value=Call(func=Attribute(
            value=Attribute(value=Name(id='sys', ctx=Load()),
                            attr='path', ctx=Load()),
            attr='append',
            ctx=Load()),
            args=[Constant(value=path_to_tracer, kind=None)],
            keywords=[]))
        )
        node.body.append(Import(names=[alias(name='Tracer', asname=None)]))
        for globalvar in self.globalvars:
            node.body.append(globalvar)
        for method in self.methods:
            node.body.append(method)
        node.body.extend(node_body)
        return node
Example #9
0
 def test_param2argparse_param_none_default(self) -> None:
     """
     Tests that param2argparse_param works to reparse the default
     """
     run_ast_test(
         gen_ast=param2argparse_param(("yup", {
             "default": NoneStr
         })),
         gold=Expr(
             Call(
                 args=[set_value("--yup")],
                 func=Attribute(
                     Name("argument_parser", Load()),
                     "add_argument",
                     Load(),
                 ),
                 keywords=[
                     keyword(arg="type",
                             value=Name("str", Load()),
                             identifier=None),
                     keyword(arg="default",
                             value=set_value(None),
                             identifier=None),
                 ],
                 expr=None,
                 expr_func=None,
             )),
         test_case_instance=self,
     )
    def compile_call(self, srcnode, parent):
        fn = srcnode.function
        if '(' not in fn:
            fn += '()'
        call = parse_and_strip(fn)[0].value
        leftovers = im.ContainerNode()
        for item in srcnode.children:
            if isinstance(item, im.CallKeyword):
                funcname = self.unique_id(item.name)
                self._compile_function(item, parent, funcname)
                call.keywords.append(keyword(arg=item.name,
                                             value=LoadName(funcname)))
            elif isinstance(item, im.TextNode) and re.match('^\s*$', item.content, re.S):
                continue
            else:
                leftovers.children.append(item)

        if leftovers.children:
            funcname = self.unique_id()
            self._compile_function(leftovers, parent, funcname)
            call.args.append(make_arg(funcname))
        parent.body.append(
            self.annotate_runtime_errors(
                Expr(value=Yield(Call(func=LoadName('str'),
                                      args=[call],
                                      starargs=None,
                                      kwargs=None,
                                      keywords=[]))), srcnode))
Example #11
0
    def _expand(self, syntax, target, macroname, tree, kw=None):
        """
        Transform `target` node, replacing it with the expansion result of
        aplying the named macro on the proper node and recursively treat the
        expansion as well.
        """
        macro = self.bindings[macroname]
        kw = kw or {}
        kw.update({
            'syntax': syntax,
            'to_source': unparse,
            'expand_macros': self.visit
        })
        expansion = _apply_macro(macro, tree, kw)

        if syntax == 'block':
            # I'm not sure why is all this mess
            #
            # Strategy 1: Make the last line cover the whole block.
            # Result: Covers the "with document" line, but not the last one.
            # copy_location(expansion[-1], target)
            #
            # Strategy 2: Make the second line cover the whole block.
            # Result: Covers all, unless the block is just 2 lines.
            # copy_location(expansion[1], target) # Lo mejor para largo > 2
            #
            # Strategy 3: Insert a second dummy line covering the whole block.
            # Result: Works
            dummy = Expr(value=Call(func=Name(id="id", ctx=Load()), args=[Constant(value="bogus", kind=None)], keywords=[]),
                         lineno=target.lineno)
            copy_location(dummy, target)
            expansion.insert(1, dummy)
        expansion = self._visit_expansion(expansion, target)
        return expansion
def _ensure_all_functions_yield(module):
    """
    All generated functions should contain at least one yield statement.
    This walks the ast to insert a "yield ''" in functions that
    don't otherwise produce output (eg in the case of '<py:def
    function="a"></py:def>')
    """
    functions = {}
    if YieldFrom is not None:
        yield_classes = (Yield, YieldFrom)
    else:
        yield_classes = (Yield,)
    for node, ancestors in astwalk(module):
        if isinstance(node, FunctionDef):
            functions.setdefault(node, False)
        elif isinstance(node, yield_classes):
            f = next(a for a in reversed(ancestors)
                     if isinstance(a, FunctionDef))
            functions[f] = True

    for f in functions:
        if not functions[f]:
            f.body.append(Expr(Yield(Str(s=''))))

    return module
Example #13
0
def test_ast_equal() -> None:
    a = Name(id="print", ctx=Load())
    b = Name(id="print", ctx=Load())
    assert ast_deep_equal(a, b)

    a = Expr(value=Call(
        func=Name(id="print", ctx=Load()),
        args=[Constant(value="hello, world")],
        keywords=[],
    ))
    b = Expr(value=Call(
        func=Name(id="print", ctx=Load()),
        args=[Constant(value="hello, world")],
        keywords=[],
    ))
    assert ast_deep_equal(a, b)
Example #14
0
 def visit_Expr(self, node):
     """Handle visiting an expression."""
     if isdescendable(node.value):
         node.value = self.visit(node.value)  # this allows diving into BoolOps
     if self.is_in_scope(node):
         return node
     else:
         newnode = self.try_subproc_toks(node)
         if not isinstance(newnode, Expr):
             newnode = Expr(value=newnode,
                            lineno=node.lineno,
                            col_offset=node.col_offset)
             if hasattr(node, 'max_lineno'):
                 newnode.max_lineno = node.max_lineno
                 newnode.max_col = node.max_col
         return newnode
Example #15
0
def add_method_call(
    body: List, instance: str, method: str, args: List, kwargs: List, returns: List[str], index: Optional[int] = None
) -> None:
    """Adds method call to be body of a container. By default, it appends. When
    index is specified, it inserts.

    :param body:
    :param instance:
    :param method:
    :param args:
    :param kwargs:
    :param index:
    :param returns:
    :return:
    """

    call = Call(func=get_name_attr(instance, method), args=args, keywords=kwargs)

    cont: Union[Expr, Assign, None] = None

    if not returns:
        cont = Expr(value=call)
    elif len(returns) == 1:
        # TODO AnnAssign??
        cont = Assign(targets=[Name(id=returns[0], ctx=Store())], value=call)
    else:
        cont = Assign(targets=[Tuple(elts=[Name(id=ret, ctx=Store()) for ret in returns], ctx=Store())], value=call)

    if index is None:
        body.append(cont)
    else:
        body.insert(index, cont)
Example #16
0
 def test_parse_out_param_fails(self) -> None:
     """ Test that parse_out_param throws NotImplementedError when unsupported type given """
     self.assertRaises(
         NotImplementedError,
         lambda: parse_out_param(
             Expr(
                 Call(
                     args=[set_value("--num")],
                     func=Attribute(
                         Name("argument_parser", Load()),
                         "add_argument",
                         Load(),
                     ),
                     keywords=[
                         keyword(
                             arg="type",
                             value=Subscript(
                                 expr_context_ctx=None,
                                 expr_slice=None,
                                 expr_value=None,
                             ),
                             identifier=None,
                         ),
                         keyword(
                             arg="required",
                             value=set_value(True),
                             identifier=None,
                         ),
                     ],
                     expr=None,
                     expr_func=None,
                 ))),
     )
Example #17
0
		def visitblock(self,body,kind):
			if not self.enableCodeCoverage: return
			if self.hot == None: return
			for i in reversed(range(len(body)+1)):
				versneaky0 = Expr(value=Call(func=Attribute(value=Name(id='madscience_debug_context', ctx=Load()), attr='log', ctx=Load()), args=[Num(n=self.scopes[self.hot]+i)], keywords=[]))
				body.insert(i,versneaky0)
			self.scopes[self.hot]+=len(body)
Example #18
0
    def visit_Expr(self, node: Expr) -> Expr:
        node.value = Call(func=Name(id='__autoexpr__', ctx=Load()),
                          args=[node.value],
                          keywords=[])

        fix_missing_locations(node)
        return node
Example #19
0
 def visit_Expr(self, node):
     """Handle visiting an expression."""
     if isdescendable(node.value):
         node.value = self.visit(node.value)  # this allows diving into BoolOps
     if self.is_in_scope(node):
         return node
     else:
         newnode = self.try_subproc_toks(node)
         if not isinstance(newnode, Expr):
             newnode = Expr(value=newnode,
                            lineno=node.lineno,
                            col_offset=node.col_offset)
             if hasattr(node, 'max_lineno'):
                 newnode.max_lineno = node.max_lineno
                 newnode.max_col = node.max_col
         return newnode
    def compile_extendsnode(self, srcnode, parent):
        if '$' in srcnode.href:
            value = _interpolated_str_to_ast_value(srcnode.href)
            parent.body.append(Assign(targets=[StoreName('__piglet_tmp')],
                                      value=value))
            loadcode = '__piglet_rt.load(__piglet_template, __piglet_tmp)\n'

        else:
            loadcode = ('__piglet_rt.load(__piglet_template, "{}")\n'
                        .format(srcnode.href))

        parent.body.extend(parse_and_strip(
            '__piglet_parent = {}'
            '__piglet_bases = [__piglet_parent] + __piglet_bases\n'
            .format(loadcode)))

        for n in srcnode.children:
            if isinstance(n, im.BlockNode):
                self.compile_blockreplacenode(n, parent)
            elif isinstance(n, im.DefNode):
                self._compile(n, parent)

        block_ids = [make_block_name(n.name)
                     for n in srcnode.find(im.BlockNode)]

        parent_template_call = Call(
            func=LoadAttribute('__piglet_parent', '__piglet_root__'),
            args=[],
            starargs=None,
            kwargs=None,
            keywords=([keyword(arg='__piglet_bases',
                               value=LoadName('__piglet_bases'))] +
                      [keyword(arg=str(b), value=LoadName(str(b)))
                       for b in block_ids])
        )
        add_kwarg(parent_template_call, '__piglet_extra_blocks')

        if YieldFrom is not None:
            parent.body.append(
                Expr(value=YieldFrom(value=parent_template_call)))
        else:
            loopvar = self.unique_id('loop')
            parent.body.append(
                For(target=Name(id=loopvar, ctx=Store()),
                    iter=parent_template_call,
                    body=[Expr(value=Yield(Name(id=loopvar, ctx=Load())))],
                    orelse=[]))
    def compile_translationnode(self, srcnode, parent):
        translated = Call(func=LoadName('_'),
                          args=[Str(srcnode.get_msgstr())],
                          starargs=None,
                          kwargs=None,
                          keywords=[])

        named_children = [(name, node)
                          for name, node in srcnode.named_children()
                          if name is not None]

        if not named_children:
            # Simple case - no dynamic children for placeholder replacement
            parent.body.append(Expr(value=Yield(translated)))
            return

        parent.body.append(
            Assign(targets=[StoreName('__piglet_places')],
                    value=Dict([], []))
        )

        for name, node in named_children:
            with self.collect_output(parent) as ACC:
                self._compile(node, parent)
                parent.body.append(
                    Assign(targets=[Subscript(value=LoadName('__piglet_places'),
                                              slice=Index(value=Str(name)),
                                              ctx=Store())],
                           value=Call(func=Attribute(value=Str(s=''), attr='join', ctx=Load()),
                                      args=[LoadName(ACC)],
                                      starargs=None,
                                      kwargs=None,
                                      keywords=[]))
                )

        for name, node in named_children:
            translated = Call(
                func=Attribute(value=translated, attr='replace', ctx=Load()),
                args=[Str('${{{}}}'.format(name)),
                      Subscript(value=LoadName('__piglet_places'),
                                slice=Index(value=Str(name)),
                                ctx=Load())],
                starargs=None,
                kwargs=None,
                keywords=[])
        set_pos(translated, srcnode)
        parent.body.append(Expr(value=Yield(translated)))
Example #22
0
		def visit_Return(self,node:ast.Return):
			if self.hot == None or (not self.hotHasReturnCheck and self.funcNames[self.hot] not in self.exitpatterns): return node
			# print("Assign: ",self.funcNames[self.hot])
			sin = [
				Assign(targets=[Name(id='_dbg_ret_var', ctx=Store())], value=node.value),
				Return(value=Name(id='_dbg_ret_var', ctx=Load()))
			]
			if self.hotHasReturnCheck:
				expattern = self.funcparams[self.hot]
				sin.insert(1,Expr(value=Call(func=Name(id='_dbgExit', ctx=Load()), args=[Name(id=pn+'_dbg_str_var_'+str(self.hot),ctx=Load()) for pn in expattern]+[Name(id='_dbg_ret_var', ctx=Load())], keywords=[])))
			if self.funcNames[self.hot] in self.exitpatterns:
				expattern = self.exitpatterns[self.funcNames[self.hot]]
				sin.insert(1,Expr(value=Call(func=Name(id='_dbgExit_'+self.funcNames[self.hot],ctx=Load()), args=[Name(id=pn+'_dbg_str_var_'+str(self.hot),ctx=Load()) for pn in expattern]+[Name(id='_dbg_ret_var', ctx=Load())], keywords=[])))
			for s in sin:
				ast.copy_location(s, node)
				ast.fix_missing_locations(s)
			return sin
Example #23
0
def test_selector_standalone():
    from ast import Expr, Num  # use python's builtin ast library
    Expr._priority = 0
    Num._priority = 1
    node = Expr(value=Num(n=1))
    sel = Selector(Num)
    sel.visit(node)
    assert isinstance(sel.out[0], Num)
Example #24
0
 def start(self, tree):
     from ast import Module, expr, Expr, Call, fix_missing_locations
     stmts = [
         Expr(s) if isinstance(s, expr) else s
         for s in reversed(self.statements)
     ]
     if not stmts:
         stmts.append(tree[0])
     return fix_missing_locations(Module(body=stmts, type_ignores=[]))
Example #25
0
	def end_loop(self, lineno, loop_start):
		loop = [self.update(lineno)]
		cleanup = Expr(value=Call(func=Name(id=Environment.cleanup_loop_func, ctx=Load()), args=[Num(n=lineno), Num(n=1), Name(id=Environment.iter_num, ctx=Load())]))
		loop.append(cleanup)
		
		delete = Delete(targets=[Name(id=Environment.iter_num, ctx=Del())])
		loop.append(delete)
		
		return loop
Example #26
0
def sub_expr(expr: ast.Expr, env: List[Dict[str, str]]) -> ast.Expr:
    if type(expr) == ast.Name:
        return ast.Str(env[expr.id])
    elif type(expr) == ast.Compare:
        expr = copy.deepcopy(expr)
        expr.left = sub_expr(expr.left, env)
        expr.comparators = [sub_expr(x, env) for x in expr.comparators]
        return expr
    elif type(expr) == ast.Str:
        return expr
    elif type(expr) == ast.Subscript:
        if type(expr.value) == ast.Name:
            if type(expr.slice) == ast.Index:
                return ast.Str(env[expr.value.id][expr.slice.value.n])
            elif type(expr.slice) == ast.Slice:
                return ast.Str(
                    env[expr.value.id][expr.slice.lower.n:expr.slice.upper.n])
    raise Exception(ast.dump(expr))
Example #27
0
 def parseSwitchStmt(self, exp):
     ## @ <ID/EXPR> SWITCH @( expr ) CASE {stmtlist} @( expr ) CASE {stmtlist} OTHERWISE {stmtlist} END
     ## implement as an if-elseif-else statement
     self.dbg_msg("parsing SWITCH statement")
     sw_tok = self.dequeue()
     [l, c] = sw_tok.get_line_col()
     self.inside_if = True
     lhs = exp[0]
     # enter this if-statement always
     ifstmt = IfStmt(Number(1), None, None, l, c, self.debug)
     self.if_stack.append(ifstmt)
     self.dbg_msg("parsing SWITCH-body")  #self.dbg_msg
     ptok = self.peek()
     equality_token = EzhilLexeme("=", EzhilToken.EQUALITY)
     while (ptok.kind == EzhilToken.ATRATEOF
            or ptok.kind == EzhilToken.OTHERWISE):
         self.inside_if = True
         [l, c] = ptok.get_line_col()
         if (ptok.kind == EzhilToken.ATRATEOF):
             # parse elseif branch
             self.dbg_msg("parsing CASE")
             self.match(EzhilToken.ATRATEOF)
             exp = self.valuelist()
             self.dbg_msg("parsing CASE EXPR")
             self.match(EzhilToken.CASE)
             next_stmt = self.stmtlist()
             expr = Expr(lhs, equality_token, exp[0], l, c, self.debug)
             self.dbg_msg("building an Expr " + str(expr))
             if not ifstmt.body:
                 ifstmt.expr = expr
                 ifstmt.body = next_stmt
             else:
                 case_stmt = IfStmt(expr, next_stmt, None, l, c, self.debug)
                 ifstmt.append_stmt(case_stmt)
         elif (ptok.kind == EzhilToken.OTHERWISE):
             #parse else branch
             self.dbg_msg("parsing OTHERWISE: ")
             self.match(EzhilToken.OTHERWISE)
             self.dbg_msg("parsing OTHERWISE-Body")
             self.inside_if = False
             body = self.stmtlist()
             else_stmt = ElseStmt(body, l, c, self.debug)
             if not ifstmt.body:
                 ifstmt.body = else_stmt
             else:
                 ifstmt.append_stmt(else_stmt)
             break
         else:
             self.inside_if = False
             raise ParseError(
                 "SWITCH-CASE-OTHERWISE statement syntax is messed up")
         ptok = self.peek()
         self.dbg_msg("parsing SWITCH-CASE next bits " + str(ptok))
     self.match(EzhilToken.END)
     self.inside_if = False
     self.dbg_msg("parsing -SWITCH-CASE- complete")
     return ifstmt
Example #28
0
 def visit_Assign(self, node: Assign) -> Any:
     unused = all(n for n in node.targets
                  if isinstance(n, Name) and hasattr(n, "_pyo_unused"))
     if unused:
         if has_side_effects(node.value):
             return Expr(node.value)
         else:
             return Pass()
     return node
Example #29
0
 def test_param2argparse_param_default_ast_expr_with_list(self) -> None:
     """
     Tests that param2argparse_param works to change the type based on the default
       whence said default is an ast.List inside an ast.Expr
     """
     run_ast_test(
         gen_ast=param2argparse_param((
             "byo",
             {
                 "default":
                 Expr(
                     List(
                         elts=[],
                         ctx=Load(),
                         expr=None,
                     ),
                     expr_value=None,
                 ),
                 "typ":
                 "str",
             },
         ), ),
         gold=Expr(
             Call(
                 args=[set_value("--byo")],
                 func=Attribute(
                     Name("argument_parser", Load()),
                     "add_argument",
                     Load(),
                 ),
                 keywords=[
                     keyword(arg="action",
                             value=set_value("append"),
                             identifier=None),
                     keyword(arg="required",
                             value=set_value(True),
                             identifier=None),
                 ],
                 expr=None,
                 expr_func=None,
             )),
         test_case_instance=self,
     )
Example #30
0
 def visit_Expr(self, node):
     if self.is_in_scope(node):
         return node
     else:
         newnode = self.try_subproc_toks(node)
         if not isinstance(newnode, Expr):
             newnode = Expr(value=newnode,
                            lineno=node.lineno,
                            col_offset=node.col_offset)
         return newnode
Example #31
0
def replace_node(old, new):
    """
    Replaces a node by another.
    If the new node is an expression while the old one is a statement, this function
    wraps the expression in an Expr node.
    """
    if isinstance(old, stmt) and isinstance(new, expr):
        new = Expr(value=new)
    for field, values in iter_fields(old.parent):
        try:
            values[values.index(old)] = new
            break
        except Exception:
            if old is values:
                setattr(old.parent, field, new)
                break
    new.parent = old.parent
    old.parent = None
    return new