def visit_static_for(self, node, is_grouped): # for i in ti.static(range(n)) # for i, j in ti.static(ti.ndrange(n)) # for I in ti.static(ti.grouped(ti.ndrange(n, m))) self.generic_visit(node, ['body']) if is_grouped: assert len(node.iter.args[0].args) == 1 template = ''' if 1: __ndrange_arg = 0 from taichi.lang.exception import TaichiSyntaxError if not isinstance(__ndrange_arg, ti.ndrange): raise TaichiSyntaxError("Only 'ti.ndrange' is allowed in 'ti.static(ti.grouped(...))'.") pass del a ''' t = ast.parse(template).body[0] t.body[0].value = node.iter.args[0].args[0] t.body[3] = node t.body[3].iter.args[0].args[0] = self.parse_expr('__ndrange_arg') else: t = self.parse_stmt('if 1: pass; del a') t.body[0] = node target = copy.deepcopy(node.target) target.ctx = ast.Del() if isinstance(target, ast.Tuple): for tar in target.elts: tar.ctx = ast.Del() t.body[-1].targets = [target] return t
def build_static_for(ctx, node, is_grouped): # for i in ti.static(range(n)) # for i, j in ti.static(ti.ndrange(n)) # for I in ti.static(ti.grouped(ti.ndrange(n, m))) ctx.current_control_scope().append('static') node.body = build_stmts(ctx, node.body) if is_grouped: assert len(node.iter.args[0].args) == 1 template = ''' if 1: __ndrange_arg = 0 from taichi.lang.exception import TaichiSyntaxError if not isinstance(__ndrange_arg, ti.ndrange): raise TaichiSyntaxError("Only 'ti.ndrange' is allowed in 'ti.static(ti.grouped(...))'.") pass del a ''' t = ast.parse(template).body[0] t.body[0].value = node.iter.args[0].args[0] t.body[3] = node t.body[3].iter.args[0].args[0] = parse_expr('__ndrange_arg') else: t = parse_stmt('if 1: pass; del a') t.body[0] = node target = copy.deepcopy(node.target) target.ctx = ast.Del() if isinstance(target, ast.Tuple): for tar in target.elts: tar.ctx = ast.Del() t.body[-1].targets = [target] return t
def visit_static_for(self, node): # for i in ti.static(range(n)) # for i, j in ti.static(ti.ndrange(n)) # for I in ti.static(ti.grouped(ti.ndrange(n, m))) self.generic_visit(node, ['body']) t = self.parse_stmt('if 1: pass; del a') t.body[0] = node target = copy.deepcopy(node.target) target.ctx = ast.Del() if isinstance(target, ast.Tuple): for tar in target.elts: tar.ctx = ast.Del() t.body[1].targets = [target] return t
def ctx_from_domain(GC: GenerationContext): if GC.domain == LValueDomain: return ast.Store() elif GC.domain == DeletionDomain: return ast.Del() else: return ast.Load()
def visit_struct_for(self, node, is_grouped): if not is_grouped: decorator = self.get_decorator(node.iter) if decorator == 'smart': # so smart! self.current_control_scope().append('smart') self.generic_visit(node, ['body']) t = self.parse_stmt('if 1: pass; del a') t.body[0] = node target = copy.deepcopy(node.target) target.ctx = ast.Del() if isinstance(target, ast.Tuple): for tar in target.elts: tar.ctx = ast.Del() t.body[-1].targets = [target] return t return old_visit_struct_for(self, node, is_grouped)
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 r_del(node: ast.Subscript, ctx: Context, clauses: list, rule_id): ctx.assert_clause_num_at_most(clauses, 1) clause = clauses[0] ctx.assert_no_head(clause) targets = clause.body for target in targets: ctx.assert_lvalue(target, "cannot be deleted") target = cast_to_ctx(target, ast.Del()) return copy_lineinfo( node, rule_id(targets=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 generate(self, element: Element, GC: GenerationContext): acode = element.code with GC.let(domain=ExDom): base_object_code = GC.generate(acode[1]) att_name = acode[2].code.full_name if GC.domain == LValueDomain: return ast.Attribute(base_object_code, att_name, ast.Store()) elif GC.domain == DeletionDomain: return ast.Attribute(base_object_code, att_name, ast.Del()) else: return expr_wrap( ast.Attribute(base_object_code, att_name, ast.Load()), GC)
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 ast_ctx_fixer(tree, stop, set_ctx, set_ctx_for, **kw): ctx = kw.get("ctx", None) """Fix any missing `ctx` attributes within an AST; allows you to build your ASTs without caring about that stuff and just filling it in later.""" if ("ctx" in type(tree)._fields and (not hasattr(tree, "ctx") or tree.ctx is None)): tree.ctx = ctx if type(tree) is ast.AugAssign: set_ctx_for(tree.target, ctx=ast.AugStore()) if type(tree) is ast.Attribute: set_ctx_for(tree.value, ctx=ast.Load()) if type(tree) is ast.Assign: set_ctx_for(tree.targets, ctx=ast.Store()) set_ctx_for(tree.value, ctx=ast.Load()) if type(tree) is ast.Delete: set_ctx_for(tree.targets, ctx=ast.Del())
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 visit_Delete(self, node: ast.Delete): ret = cast(ast.Delete, self.generic_visit(node)) for target in ret.targets: target.ctx = ast.Del() # type: ignore return ret
def test_Delete(self): self.verify( ast.Delete([ast.Name('X', ast.Del()), ast.Name('Y', ast.Del())]), 'del X,Y')
def delete(name): return ast.Name(id=name, ctx=ast.Del())
def __get_subscript_delete(self, name): """ Returns `del <data_var>["<name>"]`. """ return ast.Delete(targets=[self.__get_subscript(name, ast.Del())])
def del_global(self, name: str) -> stmt: return lineinfo(ast.Delete([lineinfo(ast.Name(name, ast.Del()))]))
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 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 make_delete(): """Delete(expr* targets)""" return ast.Delete(targets=[ast.Name(id="var", ctx=ast.Del())])
def _store_ex_dict(self, node: ex_ast.ExDict): node.ctx = self.ctx for each in node.values: self.visit(each) visit_Name = _store_simply visit_Subscript = _store_simply visit_Attribute = _store_simply visit_Tuple = _store_recursively visit_List = _store_recursively visit_ExDict = _store_ex_dict visit_Starred = _store_recursively _fix_store = ExprContextFixer(ast.Store()).visit _fix_del = ExprContextFixer(ast.Del()).visit class Loc: def __matmul__(self, other: t.Union[ast.AST, Tokenizer]): return { 'lineno': other.lineno, 'col_offset': other.col_offset if hasattr(other, 'col_offset') else other.colno } class LocatedError(Exception): def __init__(self, lineno: int, exc: Exception): self.lineno = lineno
def generate(self, element, GC: GenerationContext): from anoky.generation.util import expr_wrap acode = element.code if isinstance(acode, Form): head = acode.first headcode = head.code if isinstance( headcode, Identifier) and headcode.full_name in GC.special_forms: head.color = colors.SPECIAL_FORM hcname = headcode.full_name special_form = GC.special_forms[hcname] generated_code = special_form.generate(element, GC) return generated_code else: # function call # #(func arg1 arg2 arg3 ...) func_element = head #func_element_code = headcode with GC.let(domain=ExDom): func_code = GC.generate(func_element) arg_elements = acode[1:] args = [] keywords = [] for arg_element in arg_elements: arg_element_code = arg_element.code if isinstance(arg_element_code, Form): if is_form(arg_element_code, '='): # keyword argument kw_name = arg_element_code[1].code.full_name with GC.let(domain=ExDom): value_code = GC.generate(arg_element_code[2]) keywords.append(ast.keyword(kw_name, value_code)) elif is_form(arg_element_code, '*') and len(arg_element_code) == 2: # stared argument - expand as list with GC.let(domain=ExDom): arg_code = GC.generate(arg_element_code[1]) args.append(ast.Starred(arg_code, ast.Load())) elif is_form(arg_element_code, '**') and len(arg_element_code) == 2: # double starred argument - expand as kwlist assert len(arg_element_code) == 2 # verify no other dblstars already? with GC.let(domain=ExDom): arg_code = GC.generate(arg_element_code[1]) keywords.append(ast.keyword(None, arg_code)) else: # positional argument with GC.let(domain=ExDom): arg_code = GC.generate(arg_element) args.append(arg_code) else: # arg_element_code not a Form # then generate as expression with GC.let(domain=ExDom): arg_code = GC.generate(arg_element) args.append(arg_code) return expr_wrap(ast.Call(func_code, args, keywords), GC) if isinstance(acode, Seq): seq_codes = [] with GC.let(domain=ExDom): for e in acode: seq_codes.append(GC.generate(e)) if GC.domain == LVDom: return ast.Tuple(seq_codes, ast.Store()) elif GC.domain in [ExDom, SDom]: return expr_wrap(ast.Tuple(seq_codes, ast.Load()), GC) else: raise CodeGenerationError( acode.range, "Unexpected seq in domain `%s`." % str(GC.domain)) if isinstance(acode, Literal): element.color = colors.LITERAL if acode.type is str: return expr_wrap(ast.Str(acode.value), GC) elif acode.type in [int, float]: return expr_wrap(ast.Num(acode.value), GC) else: assert False if isinstance(acode, Identifier): if acode.full_name == "True": return expr_wrap(ast.NameConstant(True), GC) elif acode.full_name == "False": return expr_wrap(ast.NameConstant(False), GC) elif acode.full_name == "None": return expr_wrap(ast.NameConstant(None), GC) elif acode.full_name in GC.special_forms: element.color = colors.SPECIAL_FORM raise CodeGenerationError( acode.range, "Refering to special form `%s` by name requires the use of `the`." % acode.full_name) # elif acode.full_name in GC.macros: # raise CodeGenerationError(acode.range, # "Refering to macro `%s` by name requires the use of `the`." % acode.full_name) # elif acode.full_name in GC.id_macros: # raise CodeGenerationError(acode.range, # "Refering to identifier macro `%s` by name requires the use of `the`." % acode.full_name) elif GC.domain == LVDom: return ast.Name(acode.full_name, ast.Store()) elif GC.domain == DelDom: return ast.Name(acode.full_name, ast.Del()) else: return expr_wrap(ast.Name(acode.full_name, ast.Load()), GC)
def visit_For(self, node): if node.orelse: raise TaichiSyntaxError( "'else' clause for 'for' not supported in Taichi kernels") decorated = isinstance(node.iter, ast.Call) and isinstance( node.iter.func, ast.Attribute) and isinstance(node.iter.func.value, ast.Name) \ and node.iter.func.value.id == 'ti' is_ndrange_for = False is_static_for = False is_grouped = False if decorated: attr = node.iter.func if attr.attr == 'static': is_static_for = True elif attr.attr == 'grouped': is_grouped = True elif attr.attr == 'ndrange': is_ndrange_for = True else: raise Exception('Not supported') is_range_for = isinstance(node.iter, ast.Call) and isinstance( node.iter.func, ast.Name) and node.iter.func.id == 'range' ast.fix_missing_locations(node) if not is_ndrange_for: self.generic_visit(node, ['body']) if is_ndrange_for: template = ''' if ti.static(1): __ndrange = 0 for __ndrange_I in range(0): __I = __ndrange_I ''' t = ast.parse(template).body[0] t.body[0].value = node.iter t.body[1].iter.args[0] = self.parse_expr( '__ndrange.acc_dimensions[0]') targets = node.target if isinstance(targets, ast.Tuple): targets = [name.id for name in targets.elts] else: targets = [targets.id] loop_body = t.body[1].body for i in range(len(targets)): if i + 1 < len(targets): stmt = '__{} = __I // __ndrange.acc_dimensions[{}]'.format( targets[i], i + 1) else: stmt = '__{} = __I'.format(targets[i]) loop_body.append(self.parse_stmt(stmt)) stmt = '{} = __{} + __ndrange.bounds[{}][0]'.format( targets[i], targets[i], i) loop_body.append(self.parse_stmt(stmt)) if i + 1 < len(targets): stmt = '__I = __I - __{} * __ndrange.acc_dimensions[{}]'.format( targets[i], i + 1) loop_body.append(self.parse_stmt(stmt)) loop_body += node.body node = ast.copy_location(t, node) return self.visit(node) # further translate as a range for elif is_static_for: t = self.parse_stmt('if 1: pass; del a') t.body[0] = node target = copy.deepcopy(node.target) target.ctx = ast.Del() if isinstance(target, ast.Tuple): for tar in target.elts: tar.ctx = ast.Del() t.body[1].targets = [target] return t elif is_range_for: loop_var = node.target.id self.check_loop_var(loop_var) template = ''' if 1: {} = ti.Expr(ti.core.make_id_expr('')) ___begin = ti.Expr(0) ___end = ti.Expr(0) ___begin = ti.cast(___begin, ti.i32) ___end = ti.cast(___end, ti.i32) ti.core.begin_frontend_range_for({}.ptr, ___begin.ptr, ___end.ptr) ti.core.end_frontend_range_for() '''.format(loop_var, loop_var) t = ast.parse(template).body[0] assert len(node.iter.args) in [1, 2] if len(node.iter.args) == 2: bgn = node.iter.args[0] end = node.iter.args[1] else: bgn = self.make_constant(value=0) end = node.iter.args[0] t.body[1].value.args[0] = bgn t.body[2].value.args[0] = end t.body = t.body[:6] + node.body + t.body[6:] t.body.append(self.parse_stmt('del {}'.format(loop_var))) return ast.copy_location(t, node) else: # Struct for if isinstance(node.target, ast.Name): elts = [node.target] else: elts = node.target.elts for loop_var in elts: self.check_loop_var(loop_var.id) var_decl = ''.join( ' {} = ti.Expr(ti.core.make_id_expr(""))\n'.format(ind.id) for ind in elts) vars = ', '.join(ind.id for ind in elts) if is_grouped: template = ''' if 1: ___loop_var = 0 {} = ti.make_var_vector(size=___loop_var.loop_range().dim()) ___expr_group = ti.make_expr_group({}) ti.core.begin_frontend_struct_for(___expr_group, ___loop_var.loop_range().ptr) ti.core.end_frontend_range_for() '''.format(vars, vars) t = ast.parse(template).body[0] cut = 4 t.body[0].value = node.iter t.body = t.body[:cut] + node.body + t.body[cut:] else: template = ''' if 1: {} ___loop_var = 0 ___expr_group = ti.make_expr_group({}) ti.core.begin_frontend_struct_for(___expr_group, ___loop_var.loop_range().ptr) ti.core.end_frontend_range_for() '''.format(var_decl, vars) t = ast.parse(template).body[0] cut = len(elts) + 3 t.body[cut - 3].value = node.iter t.body = t.body[:cut] + node.body + t.body[cut:] for loop_var in reversed(elts): t.body.append(self.parse_stmt('del {}'.format(loop_var.id))) return ast.copy_location(t, node)
return Decimal(quotient), Decimal(remainder) def __pow__(self, power, modulo=None): if isinstance(power, (int, float)): power = Decimal(power) return Decimal(super(Decimal, self).__pow__(power, modulo)) def __rpow__(self, other): if isinstance(other, (int, float)): other = Decimal(other) return Decimal(super(Decimal, other).__pow__(self)) TYPE_STORE = type(ast.Store()) TYPE_LOAD = type(ast.Load()) TYPE_DEL = type(ast.Del()) TYPE_EXPR = type(ast.Expr()) MATH_CONTEXT = { 'acos': math.acos, 'acosh': math.acosh, 'asin': math.asin, 'asinh': math.asinh, 'atan': math.atan, 'atan2': math.atan2, 'atanh': math.atanh, 'ceil': math.ceil, 'copysign': math.copysign, 'cos': math.cos, 'cosh': math.cosh, 'degrees': math.degrees,
def gen_del_stmt(self, name_to_del): return ast.Delete(targets=[ast.Name(name_to_del, ast.Del())])
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
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 _astForDeleteVar(self, varName): assert varName is not None return ast.Delete(targets=[ast.Name(id=varName, ctx=ast.Del())])