def testReturnList(self): res = ast.If( ast.Call(ast.Name('tutu', ast.Load()), [ast.List([], ast.Load())], [], None, None), [ ast.Print(None, ast.Name('tralala', ast.Load()), False), ast.Print( None, ast.Call(ast.Name('toto', ast.Load()), [ast.List([], ast.Load())], [], None, None), False), ], [], ) class PrintDouble(NodeTransformerAddedStmt): def visit_Print(self, node): return [ ast.Print(None, ast.Name('tralala', ast.Load()), False), self.generic_visit(node), ] bases = node2json(res) transformed = node2json(PrintDouble().visit(self.getNodeTest())) self.assertEqual(bases, transformed)
def testAddedElementInside(self): res = ast.If( ast.Call(ast.Name('tutu', ast.Load()), [ast.List([], ast.Load())], [], None, None), [ ast.Print(None, ast.Name('tralala', ast.Load()), False), ast.Print( None, ast.Call(ast.Name('toto', ast.Load()), [ast.List([], ast.Load())], [], None, None), False), ], [], ) class PrintDouble(NodeTransformerAddedStmt): def visit_Name(self, node): if node.id == 'toto': self.statementToAdd( ast.Print(None, ast.Name('tralala', ast.Load()), False)) return node bases = node2json(res) transformed = node2json(PrintDouble().visit(self.getNodeTest())) self.assertEqual(bases, transformed)
def create_except_block(self, node): # Placeholder - to be updated to print failed tests s = '\nFunction line {}:'.format(node.lineno - 2) print_node1 = ast.Print(dest=None, values=[ast.Str(s=s)], nl=True) s = " >\t" + self.test_lines[self.except_counter] print_node2 = ast.Print(dest=None, values=[ast.Str(s=s)], nl=True) except_statement = ast.ExceptHandler(type=None, name=None, body=[print_node1, print_node2]) self.except_counter += 1 return [except_statement]
def print_stmt(self) -> ast.Print: toks = TokenList() if not toks.add(self.match(token.PRINT)): raise Exception("Expected print statement.") expr = self.expression() toks.add(self.match(token.SEMICOLON)) return ast.Print(toks, expr)
def reflection_of_example(): ref = ast.Module( ast.FunctionDef( name="example", args=ast.arguments( args=[], vararg=None, kwarg=None, defaults=[] ), body=[ ast.Assign( targets=[ast.Name(id="f", ctx=ast.Store())], value=ast.Num(n=1), ), ast.If( test=ast.Compare( left=ast.Name(id="f", ctx=ast.Load()), ops=[ast.Eq()], comparators=[ast.Num(n=1)], ), body=[ ast.Print( dest=None, values=[ast.Str(s="body")], nl=True ) ], orelse=[], ), ], decorator_list=[], ) )
def test_copy(self): oriNodes = ast.If( ast.Call(ast.Name('toto', ast.Load()), [ast.List([], ast.Load())], [], None, None), [ ast.Print( None, ast.Call(ast.Name('toto', ast.Load()), [ast.List([], ast.Load())], [], None, None), False), ], [], ) oriJson = node2json(oriNodes) goalNodes = nodeCopy(oriNodes) goalJson = node2json(goalNodes) self.assertEquals(oriJson, goalJson) self.assertIsNot(oriJson, goalJson) #test that elements are not exactly the sames, that a copy have been done for nOri, nGoal in zip(iter_nodes(oriNodes), iter_nodes(goalNodes)): self.assertIsNot(nOri, nGoal) #TODO remove once we know that same structure give same results self.assertEquals(node2json(nOri), node2json(nGoal))
def make_debug_node(self, call): expr_string = re.sub(r'\A[(](.*?)[)]\Z', r'\1', codegen.to_source(call.args[0])) debug_string = 'mdebug: {0} evaluates to {1}' #~ evalnode = ast.Call( #~ func = ast.Name(id = 'eval', ctx = ast.Load()), #~ args = [ast.Str(s = expr_string)], #~ keywords = [], #~ starargs = None, #~ kwargs = None #~ ) formatnode = ast.Call( func = ast.Attribute( value = ast.Str(s = debug_string), attr = 'format', ctx = ast.Load()), args = [ast.Str(s = expr_string), call.args[0]], keywords = [], starargs = None, kwargs = None ) printnode = ast.Print( dest = None, values = [formatnode], nl = True ) return printnode
def p_print_stmt5(self, p): ''' print_stmt : PRINT RIGHTSHIFT test COMMA test ''' raise NotImplementedError prnt = ast.Print() prnt.dest = p[3] prnt.values = [p[5]] prnt.nl = True p[0] = prnt
def python_ast(self): values = [] for ex in self.expressions: values.append(ex.python_ast()) return ast.Print(None, values, False, lineno=self.line, col_offset=self.column)
def visitPrint(self, node): #('dest', 'values', 'nl') if node.dest is not None: raise cast.CError(node, NotImplementedError, ("print '>>' operator is not allowed in openCL")) values = list(self.visit_list(node.values)) return ast.Print(None, values, node.nl)
def create_print_var(variable): """ Creates a node to print a variable """ node = ast.Print() node.nl = True node.dest = None node.values = [core_language.create_Name(variable)] return node
def new_print(self): self.expect('print') prt = stdast.Print() prt.lineno = self.i + 1 prt.nl = True expr = self.expression() if expr: prt.values = [expr] else: prt.values = [self.new_load()] return prt
def print_stmt_action(s, loc, tokens): nl = tokens[-1] != ',' values = [t for t in (tokens if nl else tokens[:-1])] if PY3: return ast.Call(func=ast.Name(id='print', ctx=ast.Load()), args=values, keywords=[], starargs=None, kwargs=None) else: return ast.Print(dest=None, values=values, nl=nl)
def getNodeTest(self): return ast.If( ast.Call(ast.Name('tutu', ast.Load()), [ast.List([], ast.Load())], [], None, None), [ ast.Print( None, ast.Call(ast.Name('toto', ast.Load()), [ast.List([], ast.Load())], [], None, None), False), ], [], )
def p_print_stmt6(self, p): ''' print_stmt : PRINT RIGHTSHIFT test COMMA print_list ''' raise NotImplementedError prnt = ast.Print() all_values = p[5] good_values = [item for item in all_values if item is not None] if all_values[-1] is None: nl = False else: nl = True prnt.dest = p[3] prnt.values = good_values prnt.nl = nl p[0] = prnt
def add_start_print_statements(tree, func_name): # Add print statements at beginning of function s = '\n======== Testing {} ========\n' format_args = [ast.Str(s=func_name)] formatted_string = ast.Attribute(value=ast.Str(s=s), attr='format', ctx=ast.Load()) call_node = ast.Call(func=formatted_string, args=format_args, keywords=[], starargs=None, kwargs=None) print_node1 = ast.Print(dest=None, values=[call_node], nl=True) num_dashes = (len('======== Testing ========') + len(func_name) + 1 - len(' Failures ')) // 2 s = num_dashes * '_' + ' Failures ' + num_dashes * '_' print_node2 = ast.Print(dest=None, values=[ast.Str(s=s)], nl=True) old_body = tree.body[0].body tree.body[0].body = [print_node1, print_node2] + old_body ast.fix_missing_locations(tree)
def compile_print_expression(self, expr): call = expr.pop(0) # print if sys.version_info[0] >= 3: call = self.compile(call) # AST changed with Python 3, we now just call it. return ast.Call(keywords=[], func=call, args=[self.compile(x) for x in expr], lineno=expr.start_line, col_offset=expr.start_column) return ast.Print(lineno=expr.start_line, col_offset=expr.start_column, dest=None, values=[self.compile(x) for x in expr], nl=True)
def test_withIterNodes(self): nodes = ast.If( ast.Call(ast.Name('toto', ast.Load()), [ast.List([], ast.Load())], [], None, None), [ ast.Print( None, ast.Call(ast.Name('toto', ast.Load()), [ast.List([], ast.Load())], [], None, None), False), ], [], ) waitedRes = 'If Call Name Load List Load Print Call Name Load List Load'.split( ' ') iterRes = [n.__class__.__name__ for n in iter_nodes(nodes)] self.assertEquals(waitedRes, iterRes)
def p_print_stmt(p): '''print_stmt : TAG_DRAW | TAG_DRAW testlist''' if len(p) == 3: if isinstance(p[2], list): p_values = p[2] else: p_values = [ p[2], ] p[0] = ast.Print(dest=None, values=p_values, nl=True, lineno=p.get_item(1).lineno, col_offset=p.get_item(1).lexpos) return
def add_end_print_statements(tree, t, p, func_name): # Add print statements at end of function s = '\n==== {}: {}/{} tests passed ====\n' format_args = [ ast.Str(s=func_name), ast.Name(id=p, ctx=ast.Load()), ast.Name(id=t, ctx=ast.Load()) ] formatted_string = ast.Attribute(value=ast.Str(s=s), attr='format', ctx=ast.Load()) call_node = ast.Call(func=formatted_string, args=format_args, keywords=[], starargs=None, kwargs=None) print_node = ast.Print(dest=None, values=[call_node], nl=True) tree.body[0].body.append(print_node) ast.fix_missing_locations(tree)
def testChange(self): res = ast.If( ast.Call(ast.Name('tutu', ast.Load()), [ast.List([], ast.Load())], [], None, None), [ ast.Print( None, ast.Call(ast.Name('titi', ast.Load()), [ast.List([], ast.Load())], [], None, None), False), ], [], ) class TotoInTiti(NodeTransformerAddedStmt): def visit_Name(self, node): return ast.Name('titi', node.ctx) if node.id == 'toto' else node bases = node2json(res) transformed = node2json(TotoInTiti().visit(self.getNodeTest())) self.assertEqual(bases, transformed)
def as_ast(dct): """See https://docs.python.org/2/library/ast.html""" if dct['ast_type'] == "Module": return ast.Module(dct["body"]) elif dct['ast_type'] == "Interactive": return ast.Interactive(dct["body"]) elif dct['ast_type'] == "Expression": return ast.Expression(dct["body"]) elif dct['ast_type'] == "Suite": return ast.Suite(dct["body"]) elif dct['ast_type'] == "FunctionDef": return ast.FunctionDef(dct["name"], dct["args"], dct["body"], dct["decorator_list"]) elif dct['ast_type'] == "ClassDef": return ast.ClassDef(dct["name"], dct["bases"], dct["body"], dct["decorator_list"]) elif dct['ast_type'] == "Return": return ast.Return(dct["value"]) elif dct['ast_type'] == "Delete": return ast.Delete(dct["targets"]) elif dct['ast_type'] == "Assign": return ast.Assign(dct["targets"], dct["value"]) elif dct['ast_type'] == "AugAssign": return ast.AugAssign(dct["target"], dct["op"], dct["value"]) elif dct['ast_type'] == "Print": return ast.Print(dct["dest"], dct["values"], dct["nl"]) elif dct['ast_type'] == "For": return ast.For(dct["target"], dct["iter"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "While": return ast.While(dct["test"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "If": return ast.If(dct["test"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "With": return ast.With(dct["context_expr"], dct["optional_vars"], dct["body"]) elif dct['ast_type'] == "Raise": return ast.Raise(dct["type"], dct["inst"], dct["tback"]) elif dct['ast_type'] == "TryExcept": return ast.TryExcept(dct["body"], dct["handlers"], dct["orelse"]) elif dct['ast_type'] == "TryFinally": return ast.TryFinally(dct["body"], dct["finalbody"]) elif dct['ast_type'] == "Assert": return ast.Assert(dct["test"], dct["msg"]) elif dct['ast_type'] == "Import": return ast.Import(dct["names"]) elif dct['ast_type'] == "ImportFrom": return ast.ImportFrom(dct["module"], dct["names"], dct["level"]) elif dct['ast_type'] == "Exec": return ast.Exec(dct["body"], dct["globals"], dct["locals"]) elif dct['ast_type'] == "Global": return ast.Global(dct["names"]) elif dct['ast_type'] == "Expr": return ast.Expr(dct["value"]) elif dct['ast_type'] == "Pass": return ast.Pass() elif dct['ast_type'] == "Break": return ast.Break() elif dct['ast_type'] == "Continue": return ast.Continue() elif dct['ast_type'] == "BoolOp": return ast.BoolOp(dct["op"], dct["values"]) elif dct['ast_type'] == "BinOp": return ast.BinOp(dct["left"], dct["op"], dct["right"]) elif dct['ast_type'] == "UnaryOp": return ast.UnaryOp(dct["op"], dct["operand"]) elif dct['ast_type'] == "Lambda": return ast.Lambda(dct["args"], dct["body"]) elif dct['ast_type'] == "IfExp": return ast.IfExp(dct["test"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "Dict": return ast.Dict(dct["keys"], dct["values"]) elif dct['ast_type'] == "Set": return ast.Set(dct["elts"]) elif dct['ast_type'] == "ListComp": return ast.ListComp(dct["elt"], dct["generators"]) elif dct['ast_type'] == "SetComp": return ast.SetComp(dct["elt"], dct["generators"]) elif dct['ast_type'] == "DictComp": return ast.DictComp(dct["key"], dct["value"], dct["generators"]) elif dct['ast_type'] == "GeneratorExp": return ast.GeneratorExp(dct["elt"], dct["generators"]) elif dct['ast_type'] == "Yield": return ast.Yield(dct["value"]) elif dct['ast_type'] == "Compare": return ast.Compare(dct["left"], dct["ops"], dct["comparators"]) elif dct['ast_type'] == "Call": return ast.Call(dct["func"], dct["args"], dct["keywords"], dct["starargs"], dct["kwargs"]) elif dct['ast_type'] == "Repr": return ast.Repr(dct["value"]) elif dct['ast_type'] == "Num": return ast.Num(dct["n"]) elif dct['ast_type'] == "Str": # Converting to ASCII return ast.Str(dct["s"].encode('ascii', 'ignore')) elif dct['ast_type'] == "Attribute": return ast.Attribute(dct["value"], dct["attr"], dct["ctx"]) elif dct['ast_type'] == "Subscript": return ast.Subscript(dct["value"], dct["slice"], dct["ctx"]) elif dct['ast_type'] == "Name": return ast.Name(dct["id"], dct["ctx"]) elif dct['ast_type'] == "List": return ast.List(dct["elts"], dct["ctx"]) elif dct['ast_type'] == "Tuple": return ast.Tuple(dct["elts"], dct["ctx"]) elif dct['ast_type'] == "Load": return ast.Load() elif dct['ast_type'] == "Store": return ast.Store() elif dct['ast_type'] == "Del": return ast.Del() elif dct['ast_type'] == "AugLoad": return ast.AugLoad() elif dct['ast_type'] == "AugStore": return ast.AugStore() elif dct['ast_type'] == "Param": return ast.Param() elif dct['ast_type'] == "Ellipsis": return ast.Ellipsis() elif dct['ast_type'] == "Slice": return ast.Slice(dct["lower"], dct["upper"], dct["step"]) elif dct['ast_type'] == "ExtSlice": return ast.ExtSlice(dct["dims"]) elif dct['ast_type'] == "Index": return ast.Index(dct["value"]) elif dct['ast_type'] == "And": return ast.And() elif dct['ast_type'] == "Or": return ast.Or() elif dct['ast_type'] == "Add": return ast.Add() elif dct['ast_type'] == "Sub": return ast.Sub() elif dct['ast_type'] == "Mult": return ast.Mult() elif dct['ast_type'] == "Div": return ast.Div() elif dct['ast_type'] == "Mod": return ast.Mod() elif dct['ast_type'] == "Pow": return ast.Pow() elif dct['ast_type'] == "LShift": return ast.LShift() elif dct['ast_type'] == "RShift": return ast.RShift() elif dct['ast_type'] == "BitOr": return ast.BitOr() elif dct['ast_type'] == "BitXor": return ast.BitXor() elif dct['ast_type'] == "BitAnd": return ast.BitAnd() elif dct['ast_type'] == "FloorDiv": return ast.FloorDiv() elif dct['ast_type'] == "Invert": return ast.Invert() elif dct['ast_type'] == "Not": return ast.Not() elif dct['ast_type'] == "UAdd": return ast.UAdd() elif dct['ast_type'] == "USub": return ast.USub() elif dct['ast_type'] == "Eq": return ast.Eq() elif dct['ast_type'] == "NotEq": return ast.NotEq() elif dct['ast_type'] == "Lt": return ast.Lt() elif dct['ast_type'] == "LtE": return ast.LtE() elif dct['ast_type'] == "Gt": return ast.Gt() elif dct['ast_type'] == "GtE": return ast.GtE() elif dct['ast_type'] == "Is": return ast.Is() elif dct['ast_type'] == "IsNot": return ast.IsNot() elif dct['ast_type'] == "In": return ast.In() elif dct['ast_type'] == "NotIn": return ast.NotIn() elif dct['ast_type'] == "comprehension": return ast.comprehension(dct["target"], dct["iter"], dct["ifs"]) elif dct['ast_type'] == "ExceptHandler": return ast.ExceptHandler(dct["type"], dct["name"], dct["body"]) elif dct['ast_type'] == "arguments": return ast.arguments(dct["args"], dct["vararg"], dct["kwarg"], dct["defaults"]) elif dct['ast_type'] == "keyword": return ast.keyword(dct["arg"], dct["value"]) elif dct['ast_type'] == "alias": return ast.alias(dct["name"], dct["asname"]) else: return dct
def get_ast(self, *arg_asts, **kwarg_asts): """Transform this object into a Python AST. When serialized and executed, the AST will do exactly the same as calling this object.""" if Primitive._DEBUG: debug_output(repr(self)) debug_output(" arg_asts: " + repr(arg_asts)) new_prim = self.fill_slots(arg_asts, kwarg_asts, convert_to_ast=True) if not new_prim.are_slots_filled(): raise PyExportError("not enough arguments") if Primitive._DEBUG: debug_output(" new_prim.arg_descs: " + repr(new_prim.arg_descs)) # extract the actual values from the (now constant) arguments (new_arg_asts, new_kwarg_asts) = new_prim.get_values_of_filled_slots( exportable_only=True) if Primitive._DEBUG: debug_output(" new_arg_asts: " + repr(new_arg_asts)) debug_output("end " + repr(self)) # SPECIAL HANDLING # # loops if self == LogoCode.prim_loop: controller = self._get_loop_controller() if controller == Primitive.controller_repeat: # 'repeat' loop num_repetitions = new_arg_asts[0] if num_repetitions.func.id == 'controller_repeat': num_repetitions = num_repetitions.args[0] repeat_iter = get_call_ast("range", [num_repetitions]) # TODO use new variable name in nested loops loop_ast = ast.For(target=ast.Name(id="i", ctx=ast.Store), iter=repeat_iter, body=new_arg_asts[1], orelse=[]) return loop_ast else: if controller == Primitive.controller_forever: condition_ast = ast.Name(id="True", ctx=ast.Load) elif controller == Primitive.controller_while: condition_ast = new_arg_asts[0].args[0] elif controller == Primitive.controller_until: pos_cond_ast = new_arg_asts[0].args[0] condition_ast = ast.UnaryOp(op=ast.Not, operand=pos_cond_ast) else: raise PyExportError("unknown loop controller: " + repr(controller)) loop_ast = ast.While(test=condition_ast, body=new_arg_asts[1], orelse=[]) # Until always executes its body once. if controller == Primitive.controller_until: loop_list = [] for arg_ast in new_arg_asts[1]: loop_list.append(arg_ast) loop_list.append(loop_ast) return loop_list else: return loop_ast # conditionals elif self in (LogoCode.prim_if, LogoCode.prim_ifelse): test = new_arg_asts[0] body = new_arg_asts[1] if len(new_arg_asts) > 2: orelse = new_arg_asts[2] else: orelse = [] if_ast = ast.If(test=test, body=body, orelse=orelse) return if_ast # boxes elif self == LogoCode.prim_set_box: target_ast = ast.Subscript(value=BOX_AST, slice=ast.Index(value=new_arg_asts[0]), ctx=ast.Store) return ast.Assign(targets=[target_ast], value=new_arg_asts[1]) elif self == LogoCode.prim_get_box: return ast.Subscript(value=BOX_AST, slice=ast.Index(value=new_arg_asts[0]), ctx=ast.Load) # action stacks elif self == LogoCode.prim_define_stack: return elif self == LogoCode.prim_invoke_stack: stack_func = ast.Subscript( value=ACTION_AST, slice=ast.Index(value=new_arg_asts[0]), ctx=ast.Load) call_ast = get_call_ast('logo.icall', [stack_func]) return [call_ast, ast_yield_true()] # stop stack elif self == LogoCode.prim_stop_stack: return ast.Return() # sleep/ wait elif self == LogoCode.prim_wait: return [get_call_ast('sleep', new_arg_asts), ast_yield_true()] # standard operators elif self.func.__name__ in Primitive.STANDARD_OPERATORS: op = Primitive.STANDARD_OPERATORS[self.func.__name__] # 'divide': prevent unwanted integer division if self == Primitive.divide: def _is_float(x): return get_type(x)[0] == TYPE_FLOAT if (not _is_float(new_arg_asts[0]) and not _is_float(new_arg_asts[1])): new_arg_asts[0] = get_call_ast('float', [new_arg_asts[0]], return_type=TYPE_FLOAT) if len(new_arg_asts) == 1: if isinstance(op, tuple): op = op[0] return ast.UnaryOp(op=op, operand=new_arg_asts[0]) elif len(new_arg_asts) == 2: if isinstance(op, tuple): op = op[1] (left, right) = new_arg_asts if issubclass(op, ast.boolop): return ast.BoolOp(op=op, values=[left, right]) elif issubclass(op, ast.cmpop): return ast.Compare(left=left, ops=[op], comparators=[right]) else: return ast.BinOp(op=op, left=left, right=right) # f(x) elif self == LogoCode.prim_myfunction: param_asts = [] for id_ in ['x', 'y', 'z'][:len(new_arg_asts)-1]: param_asts.append(ast.Name(id=id_, ctx=ast.Param)) func_ast = ast_extensions.LambdaWithStrBody( body_str=new_arg_asts[0].s, args=param_asts) return get_call_ast(func_ast, new_arg_asts[1:], return_type=self.return_type) # square root elif self == Primitive.square_root: return get_call_ast('sqrt', new_arg_asts, new_kwarg_asts, return_type=self.return_type) # random elif self in (Primitive.random_char, Primitive.random_int): uniform_ast = get_call_ast('uniform', new_arg_asts) round_ast = get_call_ast('round', [uniform_ast, ast.Num(n=0)]) int_ast = get_call_ast('int', [round_ast], return_type=TYPE_INT) if self == Primitive.random_char: chr_ast = get_call_ast('chr', [int_ast], return_type=TYPE_CHAR) return chr_ast else: return int_ast # identity elif self == Primitive.identity: return new_arg_asts[0] # constant elif self == CONSTANTS.get: return TypedSubscript(value=ast.Name(id='CONSTANTS', ctx=ast.Load), slice_=ast.Index(value=new_arg_asts[0]), return_type=self.return_type) # group of Primitives or sandwich-clamp block elif self in (Primitive.group, LogoCode.prim_clamp): ast_list = [] for prim in new_arg_asts[0]: if export_me(prim): new_ast = value_to_ast(prim) if isinstance(new_ast, ast.AST): ast_list.append(new_ast) return ast_list # set turtle elif self == LogoCode.prim_turtle: text = 'turtle = turtles.get_active_turtle()' return [get_call_ast('logo.prim_turtle', new_arg_asts), ast_extensions.ExtraCode(text)] elif self == LogoCode.active_turtle: text = 'turtle = turtles.get_active_turtle()' return ast_extensions.ExtraCode(text) # comment elif self == Primitive.comment: if isinstance(new_arg_asts[0], ast.Str): text = ' ' + str(new_arg_asts[0].s) else: text = ' ' + str(new_arg_asts[0]) return ast_extensions.Comment(text) # print elif self == TurtleArtWindow.print_: func_name = self.get_name_for_export() call_ast = get_call_ast(func_name, new_arg_asts) print_ast = ast.Print(values=new_arg_asts[:1], dest=None, nl=True) return [call_ast, print_ast] # heap elif self == LogoCode.get_heap: return TypedName(id_='logo.heap', return_type=self.return_type) elif self == LogoCode.reset_heap: target_ast = ast.Name(id='logo.heap', ctx=ast.Store) value_ast = ast.List(elts=[], ctx=ast.Load) return ast.Assign(targets=[target_ast], value=value_ast) # NORMAL FUNCTION CALL # else: func_name = self.get_name_for_export() return get_call_ast(func_name, new_arg_asts, new_kwarg_asts, return_type=self.return_type)
def from_phpast(node): if node is None: return py.Pass(**pos(node)) if isinstance(node, str): return py.Str(node, **pos(node)) if isinstance(node, (int, float)): return py.Num(node, **pos(node)) if isinstance(node, php.Array): if node.nodes: if node.nodes[0].key is not None: keys = [] values = [] for elem in node.nodes: keys.append(from_phpast(elem.key)) values.append(from_phpast(elem.value)) return py.Dict(keys, values, **pos(node)) else: return py.List([from_phpast(x.value) for x in node.nodes], py.Load(**pos(node)), **pos(node)) else: return py.List([], py.Load(**pos(node)), **pos(node)) if isinstance(node, php.InlineHTML): args = [py.Str(node.data, **pos(node))] return py.Call( py.Name('inline_html', py.Load(**pos(node)), **pos(node)), args, [], None, None, **pos(node)) if isinstance(node, php.Echo): return py.Call(py.Name('echo', py.Load(**pos(node)), **pos(node)), list(map(from_phpast, node.nodes)), [], None, None, **pos(node)) if isinstance(node, php.Print): return py.Print(None, [from_phpast(node.node)], True, **pos(node)) if isinstance(node, php.Exit): args = [] if node.expr is not None: args.append(from_phpast(node.expr)) return py.Raise( py.Call(py.Name('Exit', py.Load(**pos(node)), **pos(node)), args, [], None, None, **pos(node)), None, None, **pos(node)) if isinstance(node, php.Return): if node.node is None: return py.Return(None, **pos(node)) else: return py.Return(from_phpast(node.node), **pos(node)) if isinstance(node, php.Break): assert node.node is None, 'level on break not supported' return py.Break(**pos(node)) if isinstance(node, php.Continue): assert node.node is None, 'level on continue not supported' return py.Continue(**pos(node)) if isinstance(node, php.Silence): return from_phpast(node.expr) if isinstance(node, php.Block): return from_phpast(php.If(1, node, [], None, lineno=node.lineno)) if isinstance(node, php.Unset): return py.Delete(list(map(from_phpast, node.nodes)), **pos(node)) if isinstance(node, php.IsSet) and len(node.nodes) == 1: if isinstance(node.nodes[0], php.ArrayOffset): return py.Compare(from_phpast(node.nodes[0].expr), [py.In(**pos(node))], [from_phpast(node.nodes[0].node)], **pos(node)) if isinstance(node.nodes[0], php.ObjectProperty): return py.Call( py.Name('hasattr', py.Load(**pos(node)), **pos(node)), [ from_phpast(node.nodes[0].node), from_phpast(node.nodes[0].name) ], [], None, None, **pos(node)) if isinstance(node.nodes[0], php.Variable): return py.Compare(py.Str( node.nodes[0].name[1:], **pos(node)), [py.In(**pos(node))], [ py.Call(py.Name('vars', py.Load(**pos(node)), **pos(node)), [], [], None, None, **pos(node)) ], **pos(node)) return py.Compare(from_phpast(node.nodes[0]), [py.IsNot(**pos(node))], [py.Name('None', py.Load(**pos(node)), **pos(node))], **pos(node)) if isinstance(node, php.Empty): return from_phpast( php.UnaryOp('!', php.BinaryOp('&&', php.IsSet([node.expr], lineno=node.lineno), node.expr, lineno=node.lineno), lineno=node.lineno)) if isinstance(node, php.Assignment): if (isinstance(node.node, php.ArrayOffset) and node.node.expr is None): return py.Call( py.Attribute(from_phpast(node.node.node), 'append', py.Load(**pos(node)), **pos(node)), [from_phpast(node.expr)], [], None, None, **pos(node)) if (isinstance(node.node, php.ObjectProperty) and isinstance(node.node.name, php.BinaryOp)): return to_stmt( py.Call(py.Name('setattr', py.Load(**pos(node)), **pos(node)), [ from_phpast(node.node.node), from_phpast(node.node.name), from_phpast(node.expr) ], [], None, None, **pos(node))) return py.Assign([store(from_phpast(node.node))], from_phpast(node.expr), **pos(node)) if isinstance(node, php.ListAssignment): return py.Assign([ py.Tuple(list(map(store, list(map(from_phpast, node.nodes)))), py.Store(**pos(node)), **pos(node)) ], from_phpast(node.expr), **pos(node)) if isinstance(node, php.AssignOp): return from_phpast( php.Assignment(node.left, php.BinaryOp(node.op[:-1], node.left, node.right, lineno=node.lineno), False, lineno=node.lineno)) if isinstance(node, (php.PreIncDecOp, php.PostIncDecOp)): return from_phpast( php.Assignment(node.expr, php.BinaryOp(node.op[0], node.expr, 1, lineno=node.lineno), False, lineno=node.lineno)) if isinstance(node, php.ArrayOffset): return py.Subscript(from_phpast(node.node), py.Index(from_phpast(node.expr), **pos(node)), py.Load(**pos(node)), **pos(node)) if isinstance(node, php.ObjectProperty): if isinstance(node.name, (php.Variable, php.BinaryOp)): return py.Call( py.Name('getattr', py.Load(**pos(node)), **pos(node)), [from_phpast(node.node), from_phpast(node.name)], [], None, None, **pos(node)) return py.Attribute(from_phpast(node.node), node.name, py.Load(**pos(node)), **pos(node)) if isinstance(node, php.Constant): name = node.name if name.lower() == 'true': name = 'True' if name.lower() == 'false': name = 'False' if name.lower() == 'null': name = 'None' return py.Name(name, py.Load(**pos(node)), **pos(node)) if isinstance(node, php.Variable): name = node.name[1:] if name == 'this': name = 'self' return py.Name(name, py.Load(**pos(node)), **pos(node)) if isinstance(node, php.Global): return py.Global([var.name[1:] for var in node.nodes], **pos(node)) if isinstance(node, php.Include): once = py.Name('True' if node.once else 'False', py.Load(**pos(node)), **pos(node)) return py.Call(py.Name('include', py.Load(**pos(node)), **pos(node)), [from_phpast(node.expr), once], [], None, None, **pos(node)) if isinstance(node, php.Require): once = py.Name('True' if node.once else 'False', py.Load(**pos(node)), **pos(node)) return py.Call(py.Name('require', py.Load(**pos(node)), **pos(node)), [from_phpast(node.expr), once], [], None, None, **pos(node)) if isinstance(node, php.UnaryOp): op = unary_ops.get(node.op) assert op is not None, "unknown unary operator: '%s'" % node.op op = op(**pos(node)) return py.UnaryOp(op, from_phpast(node.expr), **pos(node)) if isinstance(node, php.BinaryOp): if node.op == '.': pattern, pieces = build_format(node.left, node.right) if pieces: return py.BinOp( py.Str(pattern, **pos(node)), py.Mod(**pos(node)), py.Tuple(list(map(from_phpast, pieces)), py.Load(**pos(node)), **pos(node)), **pos(node)) else: return py.Str(pattern % (), **pos(node)) if node.op in bool_ops: op = bool_ops[node.op](**pos(node)) return py.BoolOp(op, [from_phpast(node.left), from_phpast(node.right)], **pos(node)) if node.op in cmp_ops: op = cmp_ops[node.op](**pos(node)) return py.Compare(from_phpast(node.left), [op], [from_phpast(node.right)], **pos(node)) op = binary_ops.get(node.op) if node.op == 'instanceof': return py.Call( func=py.Name(id='isinstance', ctx=py.Load(**pos(node))), args=[from_phpast(node.left), from_phpast(node.right)], keywords=[], starargs=None, kwargs=None) assert op is not None, "unknown binary operator: '%s'" % node.op op = op(**pos(node)) return py.BinOp(from_phpast(node.left), op, from_phpast(node.right), **pos(node)) if isinstance(node, php.TernaryOp): return py.IfExp(from_phpast(node.expr), from_phpast(node.iftrue), from_phpast(node.iffalse), **pos(node)) if isinstance(node, php.Cast): return py.Call( py.Name(casts.get(node.type, node.type), py.Load(**pos(node)), **pos(node)), [from_phpast(node.expr)], [], None, None, **pos(node)) if isinstance(node, php.If): orelse = [] if node.else_: for else_ in map(from_phpast, deblock(node.else_.node)): orelse.append(to_stmt(else_)) for elseif in reversed(node.elseifs): orelse = [ py.If( from_phpast(elseif.expr), list( map(to_stmt, list(map(from_phpast, deblock(elseif.node))))), orelse, **pos(node)) ] return py.If( from_phpast(node.expr), list(map(to_stmt, list(map(from_phpast, deblock(node.node))))), orelse, **pos(node)) if isinstance(node, php.For): assert node.test is None or len(node.test) == 1, \ 'only a single test is supported in for-loops' return from_phpast( php.Block((node.start or []) + [ php.While(node.test[0] if node.test else 1, php.Block(deblock(node.node) + (node.count or []), lineno=node.lineno), lineno=node.lineno) ], lineno=node.lineno)) if isinstance(node, php.Foreach): if node.keyvar is None: target = py.Name(node.valvar.name[1:], py.Store(**pos(node)), **pos(node)) else: target = py.Tuple([ py.Name(node.keyvar.name[1:], py.Store(**pos(node))), py.Name(node.valvar.name[1:], py.Store(**pos(node))) ], py.Store(**pos(node)), **pos(node)) return py.For( target, from_phpast(node.expr), list(map(to_stmt, list(map(from_phpast, deblock(node.node))))), [], **pos(node)) if isinstance(node, php.While): return py.While( from_phpast(node.expr), list(map(to_stmt, list(map(from_phpast, deblock(node.node))))), [], **pos(node)) if isinstance(node, php.DoWhile): condition = php.If(php.UnaryOp('!', node.expr, lineno=node.lineno), php.Break(None, lineno=node.lineno), [], None, lineno=node.lineno) return from_phpast( php.While(1, php.Block(deblock(node.node) + [condition], lineno=node.lineno), lineno=node.lineno)) if isinstance(node, php.Try): return py.TryExcept( list(map(to_stmt, list(map(from_phpast, node.nodes)))), [ py.ExceptHandler( py.Name(catch.class_, py.Load(**pos(node)), **pos(node)), store(from_phpast(catch.var)), list(map(to_stmt, list(map(from_phpast, catch.nodes)))), **pos(node)) for catch in node.catches ], [], **pos(node)) if isinstance(node, php.Throw): return py.Raise(from_phpast(node.node), None, None, **pos(node)) if isinstance(node, php.Function): args = [] defaults = [] for param in node.params: args.append( py.Name(param.name[1:], py.Param(**pos(node)), **pos(node))) if param.default is not None: defaults.append(from_phpast(param.default)) body = list(map(to_stmt, list(map(from_phpast, node.nodes)))) if not body: body = [py.Pass(**pos(node))] return py.FunctionDef(node.name, py.arguments(args, None, None, defaults), body, [], **pos(node)) if isinstance(node, php.Method): args = [] defaults = [] decorator_list = [] if 'static' in node.modifiers: decorator_list.append( py.Name('classmethod', py.Load(**pos(node)), **pos(node))) args.append(py.Name('cls', py.Param(**pos(node)), **pos(node))) else: args.append(py.Name('self', py.Param(**pos(node)), **pos(node))) for param in node.params: args.append( py.Name(param.name[1:], py.Param(**pos(node)), **pos(node))) if param.default is not None: defaults.append(from_phpast(param.default)) body = list(map(to_stmt, list(map(from_phpast, node.nodes)))) if not body: body = [py.Pass(**pos(node))] return py.FunctionDef(node.name, py.arguments(args, None, None, defaults), body, decorator_list, **pos(node)) if isinstance(node, php.Class): name = node.name bases = [] extends = node.extends or 'object' bases.append(py.Name(extends, py.Load(**pos(node)), **pos(node))) body = list(map(to_stmt, list(map(from_phpast, node.nodes)))) for stmt in body: if (isinstance(stmt, py.FunctionDef) and stmt.name in (name, '__construct')): stmt.name = '__init__' if not body: body = [py.Pass(**pos(node))] return py.ClassDef(name, bases, body, [], **pos(node)) if isinstance(node, (php.ClassConstants, php.ClassVariables)): assert len(node.nodes) == 1, \ 'only one class-level assignment supported per line' if isinstance(node.nodes[0], php.ClassConstant): name = php.Constant(node.nodes[0].name, lineno=node.lineno) else: name = php.Variable(node.nodes[0].name, lineno=node.lineno) initial = node.nodes[0].initial if initial is None: initial = php.Constant('None', lineno=node.lineno) return py.Assign([store(from_phpast(name))], from_phpast(initial), **pos(node)) if isinstance(node, (php.FunctionCall, php.New)): if isinstance(node.name, str): name = py.Name(node.name, py.Load(**pos(node)), **pos(node)) else: name = py.Subscript( py.Call(py.Name('vars', py.Load(**pos(node)), **pos(node)), [], [], None, None, **pos(node)), py.Index(from_phpast(node.name), **pos(node)), py.Load(**pos(node)), **pos(node)) args, kwargs = build_args(node.params) return py.Call(name, args, kwargs, None, None, **pos(node)) if isinstance(node, php.MethodCall): args, kwargs = build_args(node.params) return py.Call( py.Attribute(from_phpast(node.node), node.name, py.Load(**pos(node)), **pos(node)), args, kwargs, None, None, **pos(node)) if isinstance(node, php.StaticMethodCall): class_ = node.class_ if class_ == 'self': class_ = 'cls' args, kwargs = build_args(node.params) return py.Call( py.Attribute(py.Name(class_, py.Load(**pos(node)), **pos(node)), node.name, py.Load(**pos(node)), **pos(node)), args, kwargs, None, None, **pos(node)) if isinstance(node, php.StaticProperty): class_ = node.node name = node.name if isinstance(name, php.Variable): name = name.name[1:] return py.Attribute(py.Name(class_, py.Load(**pos(node)), **pos(node)), name, py.Load(**pos(node)), **pos(node)) return py.Call(py.Name('XXX', py.Load(**pos(node)), **pos(node)), [py.Str(str(node), **pos(node))], [], None, None, **pos(node))
def p_print_statement(self, p): """ print_statement : PRINT LPAREN expression_opt RPAREN SEMI """ p[0] = ast.Print(p[3], coord=self._token_coord(p, 1))
def visit_Print(self, node): return [[ [[ast.Print(None, ast.Name('tralala', ast.Load()), False)]], self.generic_visit(node), ]]
# -*- coding: utf-8 -*- ''' Created on 2018年4月30日 @author: Administrator ''' import ast hello_world = ast.Str(s='hello world', lineno=1, col_offset=1) print_call = ast.Print(values=[hello_world], lineno=1, col_offset=1, nl=True) module = ast.Module(body=[print_call]) code = compile(module, '', 'exec') eval(code) if __name__ == '__main__': pass
def test_copy(self): oriNodes = ast.If( ast.Call(ast.Name('toto', ast.Load()), [ast.List([], ast.Load())], [], None, None), [ ast.Print( None, ast.Call(ast.Name('toto', ast.Load()), [ast.List([], ast.Load())], [], None, None), False), ], [], ) jsonOriNodes = { 'test': { 'starargs': 'None', 'args': [{ 'elts': [], 'ctx': { '__class__': 'Load' }, '__class__': 'List' }], '__class__': 'Call', 'func': { 'ctx': { '__class__': 'Load' }, '__class__': 'Name', 'id': 'toto' }, 'kwargs': 'None', 'keywords': [] }, 'body': [{ 'dest': 'None', 'nl': 'False', 'values': { 'starargs': 'None', 'args': [{ 'elts': [], 'ctx': { '__class__': 'Load' }, '__class__': 'List' }], '__class__': 'Call', 'func': { 'ctx': { '__class__': 'Load' }, '__class__': 'Name', 'id': 'toto' }, 'kwargs': 'None', 'keywords': [] }, '__class__': 'Print' }], '__class__': 'If', 'orelse': [] } jsonNodes = node2json(oriNodes) self.assertEquals(jsonOriNodes, jsonNodes)
def visit_Print(self, node): self.statementToAdd( ast.Print(None, ast.Name('tralala', ast.Load()), False)) return self.generic_visit(node)
def visit_Name(self, node): if node.id == 'toto': self.statementToAdd( ast.Print(None, ast.Name('tralala', ast.Load()), False)) return node