def visit_Delete(self, node): """ Replace multiple deletion with single deletions. """ self.generic_visit(node) if len(node.targets) > 1: return [ ast.Delete([node.target]) for target in node.targets ] return node
def visit_Delete(self, node): statements = [] for target in node.targets: if isinstance(target, ast.Name): statements.append( mk_assign(target.id, mk_name('__pydron_unbound__'))) else: statements.append(ast.Delete(targets=[target])) return statements
def import_typing(self): self.preamble.append( ast.Import(names=[ast.alias( name="typing", asname="_typing", )], )) self.epilogue.append( ast.Delete(targets=[ ast.Name(id="_typing", ctx=ast.Del()), ]))
def import_spec(self): self.preamble.append( ast.ImportFrom( module="", names=[ast.alias("_spec", asname=None)], level=1, )) self.epilogue.append( ast.Delete(targets=[ ast.Name(id="_spec", ctx=ast.Del()), ]))
def visit_Delete(self, node): if self.inside_module(): return node statements = [] for target in node.targets: if isinstance(target, ast.Name) and self.is_global_name(target): stmt = mk_call("__pydron_delete_global__", args=[mk_str(target.id)]) statements.append(ast.Expr(stmt)) else: statements.append(ast.Delete(targets=[target])) return statements
def generate_delete(max_depth=None): num_nodes = random.randrange(1, 4) choices = [ generate_variable, generate_attribute, generate_subscript, ] targets = [ tar(max_depth=max_depth, ctx=ast.Store()) for tar in random.choices(choices, k=num_nodes) ] return ast.Delete(targets)
def p_del_stmt(p): '''del_stmt : TAG_DEL exprlist''' targets = p[2] if not isinstance(targets, list): targets = [ p[2], ] set_context(targets, ast.Del()) p[0] = ast.Delete(targets=targets, lineno=p.get_item(1).lineno, col_offset=p.get_item(1).lexpos) return
def p_exec_start(p, stmts=2): """exec_start : skipnl suite""" my_module = colon_assignment_target(p) fn_name = '<my-module>' fn_args = ast_arguments([ast_arg(my_module.id)]) fn_node = ast_funcdef(fn_name, fn_args, stmts) fn_call = ast_call(ast_name(fn_name), [my_module]) try_node = ast.TryFinally([ast.Expr(fn_call)], [ast.Delete([ast_name(fn_name, ast.Del())])]) module_body = [fn_node, try_node] doc_node = docstring(stmts) if doc_node is not None: module_body.insert(0, doc_node) return ast.Module(module_body)
def test_simple_statements(self): # Simple statements can be put on a single line as long as the scope # has not changed. for body, expect in [ (ast.Expr(ast.Num(42)), '42'), (ast.Import([ast.alias('a', None)]), 'import a'), (ast.ImportFrom('b', [ast.alias('a', None)], 1), 'from .b import a'), (ast.Break(), 'break'), (ast.Continue(), 'continue'), (ast.Pass(), 'pass'), (ast.Assign([ast.Name('X', ast.Store())], ast.Num(42)), 'X=42'), (ast.Delete([ast.Name('X', ast.Del())]), 'del X'), (ast.Raise(None, None), 'raise'), (ast.Return(None), 'return'), (ast.AugAssign(ast.Name('X', ast.Store()), ast.Add(), ast.Num(42)), 'X+=42'), (ast.Assert(ast.Num(42), None), 'assert 42'), (ast.Global(['x']), 'global x'), (ast.Nonlocal(['x']), 'nonlocal x'), ]: if_simple = ast.If(ast.Num(42), [body], None) self.verify(if_simple, 'if 42:{}'.format(expect)) if_multiple_simples = ast.If(ast.Num(42), [ast.Pass(), ast.Pass()], None) self.verify(if_multiple_simples, 'if 42:pass;pass') inner_if = ast.If(ast.Num(6), [ast.Pass()], None) funky_if = ast.If(ast.Num(42), [ ast.Break(), ast.Continue(), inner_if, ast.Break(), ast.Continue() ], None) self.verify(funky_if, 'if 42:\n break;continue\n if 6:pass\n break;continue')
def visit_Assert(self, assert_): if assert_.msg: # There's already a message. Don't mess with it. return [assert_] self.statements = [] self.variables = set() self.variable_counter = itertools.count() self.stack = [] self.on_failure = [] self.push_format_context() # Rewrite assert into a bunch of statements. top_condition, explanation = self.visit(assert_.test) # Create failure message. body = self.on_failure negation = ast.UnaryOp(ast.Not(), top_condition) self.statements.append(ast.If(negation, body, [])) explanation = "assert " + explanation template = ast.Str(explanation) msg = self.pop_format_context(template) fmt = self.helper("format_explanation", msg) err_name = ast.Name("AssertionError", ast.Load()) exc = ast.Call(err_name, [fmt], [], None, None) if sys.version_info[0] >= 3: raise_ = ast.Raise(exc, None) else: raise_ = ast.Raise(exc, None, None) body.append(raise_) # Delete temporary variables. names = [ast.Name(name, ast.Del()) for name in self.variables] if names: delete = ast.Delete(names) self.statements.append(delete) # Fix line numbers. for stmt in self.statements: set_location(stmt, assert_.lineno, assert_.col_offset) return self.statements
def test_Delete(self): self.verify( ast.Delete([ast.Name('X', ast.Del()), ast.Name('Y', ast.Del())]), 'del X,Y')
def test_delete(self): self.stmt(ast.Delete([]), "empty targets on Delete") self.stmt(ast.Delete([None]), "None disallowed") self.stmt(ast.Delete([ast.Name("x", ast.Load())]), "must have Del context")
def del_global(self, name: str) -> stmt: return lineinfo(ast.Delete([lineinfo(ast.Name(name, ast.Del()))]))
def Delete(draw): return ast.Delete( targets=draw(lists(expression(), min_size=1, max_size=3)))
def __get_subscript_delete(self, name): """ Returns `del <data_var>["<name>"]`. """ return ast.Delete(targets=[self.__get_subscript(name, ast.Del())])
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") if self.resource.package_name != self.resource.base.package_name: self.generator.import_resource( self.resource.package_name, self.resource.base.package_name, 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, kind=None))) # 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, kind=None)), ) ]), ) return class_node
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") if self.resource.package_name != self.resource.base.package_name: self.generator.import_resource( self.resource.package_name, self.resource.base.package_name, 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, kind=None))) # Add the field definitions for prop in self.resource.properties: node = self._create_schema_property(prop) if node: class_node.body.append(node) # Properties set by marshmallow Schema confuses mypy. It thinks # the class properties conflict, however since the fields # defined here are removed by a metaclass this isn't the case # simple workaround to silicen these if prop.name in ["fields"]: class_node.body.append(ast.Name(id=" # type: ignore")) # 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")) # if the parent type doesn't accept any keyword args then don't # generate the **data kwarg to make mypy happy. # Special care here for discriminator fields where we don't want to # pass it from subclasses but do want to pass it to base classes all_properties = self.resource.get_all_properties() d_field = self.resource.get_discriminator_field() if d_field and d_field not in self.resource.properties: all_properties.remove(d_field) type_init_keywords = [] if len(all_properties) > 0: type_init_keywords = [ ast.keyword(arg=None, value=ast.Name(id="data")) ] post_load_node.body.append( ast.Return(value=ast.Call( func=ast.Name(id=f"types.{self.resource.name}"), args=[], keywords=type_init_keywords, ))) 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) 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, kind=None)), ) ]), ) return class_node
def from_phpast(self, node): if node is None: return py.Name('None', py.Load(**pos(node)), **pos(node)) if isinstance(node, basestring): return py.Str(node, **pos(node)) if isinstance(node, (int, float, long)): 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(self.from_phpast(elem.key)) values.append(self.from_phpast(elem.value)) ds = py.Dict(keys, values, **pos(node)) else: ds = py.List([self.from_phpast(x.value) for x in node.nodes], py.Load(**pos(node)), **pos(node)) else: ds = py.List([], py.Load(**pos(node)), **pos(node)) return py.Call(py.Name('PHPArray', py.Load(**pos(node)), **pos(node)), [ds], [], None, None, **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)), map(self.from_phpast, node.nodes), [], None, None, **pos(node)) if isinstance(node, php.Print): return py.Print(None, [self.from_phpast(node.node)], True, **pos(node)) if isinstance(node, php.Exit): args = [] if node.expr is not None: args.append(self.from_phpast(node.expr)) return py.Raise(py.Call(py.Name('SystemExit', py.Load(**pos(node)), **pos(node)), args, [], None, None, **pos(node)), None, None, **pos(node)) if isinstance(node, php.Return): if len(self.scope_stack) > 0: # return from function if node.node is None: return py.Return(None, **pos(node)) else: return py.Return(self.from_phpast(node.node), **pos(node)) else: # return from script args = [self.from_phpast(node.node)] return py.Raise(py.Call(py.Name('_GlobalReturn', py.Load(**pos(node)), **pos(node)), args, [], None, None, **pos(node)), None, None, **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 self.from_phpast(node.expr) if isinstance(node, php.Block): return self.from_phpast(php.If(1, node, [], None, lineno=node.lineno)) if isinstance(node, php.Unset): return py.Delete(map(self.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(self.from_phpast(node.nodes[0].expr), [py.In(**pos(node))], [self.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)), [self.from_phpast(node.nodes[0].node), self.from_phpast(node.nodes[0].name)], [], None, None, **pos(node)) if isinstance(node.nodes[0], php.Variable): variable_name = node.nodes[0].name[1:] static_name = self.get_static(variable_name) if static_name: variable_name = static_name globs = py.Call(py.Name('globals', py.Load(**pos(node)), **pos(node)), [], [], None, None, **pos(node)) locs = py.Call(py.Name('locals', py.Load(**pos(node)), **pos(node)), [], [], None, None, **pos(node)) return py.Compare(py.Str(static_name, **pos(node)), [py.In(**pos(node))], [py.Call(py.Name('all_vars', py.Load(**pos(node)), **pos(node)), [globs, locs], [], None, None, **pos(node))], **pos(node)) return py.Compare(self.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 self.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(self.from_phpast(node.node.node), 'append', py.Load(**pos(node)), **pos(node)), [self.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(map(store, map(self.from_phpast, node.nodes)), py.Store(**pos(node)), **pos(node))], self.from_phpast(node.expr), **pos(node)) if isinstance(node, php.AssignOp): return self.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 self.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(self.from_phpast(node.node), py.Index(self.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)), [self.from_phpast(node.node), self.from_phpast(node.name)], [], None, None, **pos(node)) return py.Attribute(self.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:] static_name = self.get_static(name) if static_name: name = static_name if name == 'this': name = 'self' return py.Name(name, py.Load(**pos(node)), **pos(node))
def _astForDeleteVar(self, varName): assert varName is not None return ast.Delete(targets=[ast.Name(id=varName, ctx=ast.Del())])
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()
def visitDelete(self, n, *args): return ast.Delete( targets=[self.dispatch(target, *args) for target in n.targets])
def test_stmt(self): # def foo(): # pass fundef0 = ast.FunctionDef() fundef1 = ast.FunctionDef('foo', ast.arguments([], None, None, []), [ast.Pass()], []) fundef2 = ast.FunctionDef('foo', ast.arguments([], None, None, []), [ast.Pass()], [], 0,0 ) # class foo(object): # pass classdef0 = ast.ClassDef() classdef1 = ast.ClassDef('foo', [ast.Name('object', ast.Load())], [ast.Pass()], []) classdef1 = ast.ClassDef('foo', [ast.Name('object', ast.Load())], [ast.Pass()], [], 0,0) # return 0 return0 = ast.Return() return1 = ast.Return(ast.Num(0)) return2 = ast.Return(ast.Num(0),0,0) return20 = ast.Return(lineno=0, col_offset=0) # del d[1] del0 = ast.Delete() del1 = ast.Delete([ast.Subscript(ast.Name('d', ast.Load()), ast.Index(ast.Num(1)), ast.Del())]) del2 = ast.Delete([ast.Subscript(ast.Name('d', ast.Load()), ast.Index(ast.Num(1)), ast.Del())],0,0) # a=1 assign0=ast.Assign() assign1=ast.Assign([ast.Name('a', ast.Store())], ast.Num(1)) assign2=ast.Assign([ast.Name('a', ast.Store())], ast.Num(1),0,0) # a+=1 augassign0=ast.AugAssign() augassign1=ast.AugAssign(ast.Name('a', ast.Store()), ast.Add(), ast.Num(1)) augassign2=ast.AugAssign(ast.Name('a', ast.Store()), ast.Add(), ast.Num(1),0,0) # print 1 print0 = ast.Print() print1 = ast.Print(None, [ast.Num(1)], True) print2 = ast.Print(None, [ast.Num(1)], True, 0, 0) print20 = ast.Print( values=[ast.Num(1)], nl=True) # for i in l: # print i # else: # pass for0 = ast.For() for1 = ast.For(ast.Name('i', ast.Store()), ast.Name('l', ast.Load()), [ast.Print(None, [ast.Name('i', ast.Load())], True)], [ast.Pass()]) for2 = ast.For(ast.Name('i', ast.Store()), ast.Name('l', ast.Load()), [ast.Print(None, [ast.Name('i', ast.Load())], True)], [ast.Pass()],0,0) # while True: # pass # else: # pass while0 = ast.While() while1 = ast.While(ast.Name('True', ast.Load()), [ast.Pass()], [ast.Pass()]) while2 = ast.While(ast.Name('True', ast.Load()), [ast.Pass()], [ast.Pass()], 0,0 ) # if a: # pass # else: # pass if0 = ast.If() if1 = ast.If(ast.Name('a', ast.Load()), [ast.Pass()], [ast.Pass()]) if2 = ast.If(ast.Name('a', ast.Load()), [ast.Pass()], [ast.Pass()] ,0,0) # with with open("foo") as f: # pass with0 = ast.With() with0 = ast.With(ast.Call(ast.Name('open', ast.Load()), [ast.Str('foo')], []), ast.Name('f', ast.Store()), [ast.Pass()]) # raise Exception() raise0 = ast.Raise() raise1 = ast.Raise(ast.Call(ast.Name('Exception', ast.Load()), [], []), None, None) raise2 = ast.Raise(ast.Call(ast.Name('Exception', ast.Load()), [], []), None, None, 0, 0)
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 make_delete(): """Delete(expr* targets)""" return ast.Delete(targets=[ast.Name(id="var", ctx=ast.Del())])
def visit_Delete(self, node): """ This converter replaces bare deletes with conditional global pops. It is roughly equivalent to transforming: .. code:: python del foobar into: .. code:: python if 'foobar' in globals(): globals().pop('foobar') else: del foobar This thus makes deletions in retain mode work more-or-less as intended. """ return ast.If( test=ast.NameConstant( value=True, # if True; aka unconditional, will be optimized out lineno=node.lineno, col_offset=node.col_offset ), body=[ ast.If( # if 'x' in globals(): test=ast.Compare( # 'x' left=ast.Str( s=target.id, lineno=node.lineno, col_offset=node.col_offset ), ops=[ # in ast.In( lineno=node.lineno, col_offset=node.col_offset ) ], comparators=[ # globals() self.globals_call(node) ], lineno=node.lineno, col_offset=node.col_offset ), body=[ ast.Expr( # globals().pop('x') value=ast.Call( # globals().pop func=ast.Attribute( value=self.globals_call(node), attr='pop', ctx=ast.Load(), lineno=node.lineno, col_offset=node.col_offset ), args=[ # 'x' ast.Str( s=target.id, lineno=node.lineno, col_offset=node.col_offset ) ], keywords=[], lineno=node.lineno, col_offset=node.col_offset ), lineno=node.lineno, col_offset=node.col_offset ) ], # else: orelse=[ # del x ast.Delete( targets=[target], lineno=node.lineno, col_offset=node.col_offset ) ], lineno=node.lineno, col_offset=node.col_offset ) if isinstance(target, ast.Name) else ast.Delete( targets=[target], lineno=node.lineno, col_offset=node.col_offset ) # for each target to be deleted, e.g. `del {x}, {y}, {z}` for target in node.targets ], orelse=[], lineno=node.lineno, col_offset=node.col_offset )
def to_ast(self, modname, func, tmp_name): # tmp_name = func yield ast.Assign(targets=[ast.Name(id=tmp_name, ctx=ast.Store())], value=ast.Name(id=func.name, ctx=ast.Load())) # def func2(...): ... for node in self.body: copy_lineno(func, node) func2 = ast.FunctionDef( name=func.name, args=func.args, body=self.body, # explicitly drops decorator for the # specialized function decorator_list=[], returns=None) yield func2 if self.patch_constants: # func.__code__ = func.__code__.replace_consts({...}) dict_keys = [] dict_values = [] for key, value in self.patch_constants.items(): # FIXME: use optimizer.new_constant()? key = _new_constant(func, key) value = _new_constant(func, value) dict_keys.append(key) dict_values.append(value) mapping = ast.Dict(keys=dict_keys, values=dict_values) copy_lineno(func, mapping) mod = ast.Name(id=modname, ctx=ast.Load()) name_func = ast.Name(id=func2.name, ctx=ast.Load()) attr = ast.Attribute(value=name_func, attr='__code__', ctx=ast.Load()) call = Call(func=ast.Attribute(value=mod, attr='replace_consts', ctx=ast.Load()), args=[attr, mapping], keywords=[]) copy_lineno(func, call) target = ast.Attribute(value=name_func, attr='__code__', ctx=ast.Store()) yield ast.Assign(targets=[target], value=call) # encode guards guards = [guard.as_ast(func, modname) for guard in self.guards] guards = ast.List(elts=guards, ctx=ast.Load()) copy_lineno(func, guards) # fat.specialize(tmp_name, func2, guards) specialize = ast.Attribute(value=ast.Name(id=modname, ctx=ast.Load()), attr='specialize', ctx=ast.Load()) name_func = ast.Name(id=tmp_name, ctx=ast.Load()) code = ast.Attribute(value=ast.Name(id=func2.name, ctx=ast.Load()), attr='__code__', ctx=ast.Load()) call = Call(func=specialize, args=[name_func, code, guards], keywords=[]) yield ast.Expr(value=call) # func = tmp_name yield ast.Assign(targets=[ast.Name(id=func.name, ctx=ast.Store())], value=ast.Name(id=tmp_name, ctx=ast.Load())) # del tmp_name yield ast.Delete(targets=[ast.Name(id=tmp_name, ctx=ast.Del())])
def gen_del_stmt(self, name_to_del): return ast.Delete(targets=[ast.Name(name_to_del, ast.Del())])
def del_statement_visitor( node: concat.parse.DelStatementNode, ) -> ast.Delete: """This converts a DelStatementNode to a Python statement. The Python statement has the form of `del ...1,......,...n`.""" @assert_annotated_type def subscription_subvisitor(node: concat.parse.SubscriptionWordNode,): words = node.children quote = concat.parse.QuoteWordNode( list(words), list(words)[0].location if words else node.location, ) py_quote = visitors['quote-word'].visit(quote) load = ast.Load() stack = ast.Name(id='stack', ctx=load) stash = ast.Name(id='stash', ctx=load) quote_call = ast.Call( func=py_quote, args=[stack, stash], keywords=[] ) append_stash = ast.Attribute(value=stash, attr='append', ctx=load) append_stash_call = ast.Call( func=append_stash, args=[pop_stack()], ctx=load ) object = pack_expressions( [quote_call, append_stash_call, pop_stack()] ) pop_stash = ast.Attribute(value=stash, attr='pop', ctx=load) pop_stash_call = ast.Call(func=pop_stash, args=[], keywords=[]) index = ast.Index(value=pop_stash_call) target = ast.Subscript(value=object, slice=index, ctx=load) return target @assert_annotated_type def slice_subvisitor(node: concat.parse.SliceWordNode): to_slice_token = concat.lex.Token() to_slice_token.type, to_slice_token.value = 'NAME', 'to_slice' to_slice = concat.parse.NameWordNode(to_slice_token) subscription = concat.parse.SubscriptionWordNode( [ *node.step_children, *node.stop_children, *node.start_children, to_slice, ] ) return subscription_subvisitor.visit(subscription) subscription_subvisitor = assert_type( concat.parse.SubscriptionWordNode ).then(subscription_subvisitor) slice_subvisitor = assert_type(concat.parse.SliceWordNode).then( slice_subvisitor ) subvisitor = alt( visitors['name-word'], visitors['attribute-word'], subscription_subvisitor, slice_subvisitor, ) targets = All(subvisitor).visit(node) return ast.Delete(targets=targets)
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 _visit_With(self, with_node, element_name='__template__'): def search_ids(node): ids = [] for elt in node.elts: if isinstance(elt, ast.Name): ids.append(elt.id) else: ids.extend(search_ids(elt)) return ids if len(with_node.items) > 1: raise SyntaxError( "'with' may contain one item in template scope, '{}' template". format(self.template_name)) else: item = with_node.items[0] # if item.optional_vars: # raise SyntaxError("optional 'with' args 'as...' are not supported in template scope," # " '{}' template".format(self.template_name)) if isinstance(item.context_expr, ast.Call): call = item.context_expr if not isinstance(call.func, ast.Name): raise SyntaxError( "in template scope 'with' may contain only Element() or [element_tag]()," " '{}' template".format(self.template_name)) if item.optional_vars and isinstance(item.optional_vars, ast.Name): del_vars = False element_id = item.optional_vars.id else: del_vars = True element_id = "__{}_{}__".format(call.func.id, id(call)) _as = ast.Name(id=element_id, ctx=ast.Store()) item.optional_vars = _as if call.func.id == "Element": body = [] else: append_call = ast.Call( func=ast.Attribute(value=ast.Name(id=element_name, ctx=ast.Load()), attr='append', ctx=ast.Load()), args=[ast.Name(id=element_id, ctx=ast.Load())], keywords=[]) body = [ast.Expr(value=append_call)] for node in with_node.body: method = '_visit_' + node.__class__.__name__ visitor = getattr(self, method, None) if visitor is not None: node = visitor(node, element_id) if not isinstance(node, ast.AST): body.extend(node) else: body.append(node) if del_vars: body.append( ast.Delete( targets=[ast.Name(id=element_id, ctx=ast.Del())])) with_node.body = body return with_node