class CombineWithStatementsTests(unittest.TestCase): """with A: with B: pass with A,B:pass """ A = ast.Name('A', ast.Load()) A_clause = ast.withitem(A, None) B = ast.Name('B', ast.Load()) B_clause = ast.withitem(B, None) C = ast.Name('C', ast.Load()) C_clause = ast.withitem(C, None) def setUp(self): self.transform = mnfy.CombineWithStatements() def test_deeply_nested(self): with_C = ast.With([self.C_clause], [ast.Pass()]) with_B = ast.With([self.B_clause], [with_C]) with_A = ast.With([self.A_clause], [with_B]) new_ast = self.transform.visit(with_A) expect = ast.With([self.A_clause, self.B_clause, self.C_clause], [ast.Pass()]) self.assertEqual(ast.dump(new_ast), ast.dump(expect)) def test_no_optimization(self): with_B = ast.With([self.B_clause], [ast.Pass()]) with_A = ast.With([self.A_clause], [with_B, ast.Pass()]) new_ast = self.transform.visit(with_A) self.assertEqual(new_ast, with_A)
def test_with(self): p = ast.Pass() self.stmt(ast.With([], [p]), "empty items on With") i = ast.withitem(ast.Num(3), None) self.stmt(ast.With([i], []), "empty body on With") i = ast.withitem(ast.Name("x", ast.Store()), None) self.stmt(ast.With([i], [p]), "must have Load context") i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load())) self.stmt(ast.With([i], [p]), "must have Store context")
def compile_with_expression(self, expr): expr.pop(0) # with args = expr.pop(0) if len(args) > 2 or len(args) < 1: raise HyTypeError(expr, "with needs [arg (expr)] or [(expr)]") args.reverse() ctx = self.compile(args.pop(0)) thing = None if args != []: thing = self._storeize(self.compile(args.pop(0))) ret = ast.With(context_expr=ctx, lineno=expr.start_line, col_offset=expr.start_column, optional_vars=thing, body=self._code_branch([self.compile(x) for x in expr], expr.start_line, expr.start_column)) if sys.version_info[0] >= 3 and sys.version_info[1] >= 3: ret.items = [ast.withitem(context_expr=ctx, optional_vars=thing)] return ret
def visit_withitem(self, node: withitem, *args, **kwargs) -> C.withitem: context_expr = self.visit(node.context_expr, *args, **kwargs) optional_vars = self.visit(node.optional_vars, *args, **kwargs) return C.withitem( #context_expr=context_expr, optional_vars=optional_vars, )
def visit_stmt(self, node): # type: (ast.stmt) -> ast.With """ Every statement in the original code becomes: with _treetrace_hidden_with_stmt(_tree_index): <statement> where the _treetrace_hidden_with_stmt function is the the corresponding method with the TreeTracerBase and traced_file arguments already filled in (see _trace_methods_dict) """ context_expr = self._create_simple_marker_call( super(_NodeVisitor, self).generic_visit(node), TreeTracerBase._treetrace_hidden_with_stmt) if PY3: wrapped = ast.With( items=[ast.withitem(context_expr=context_expr)], body=[node], ) else: wrapped = ast.With( context_expr=context_expr, body=[node], ) ast.copy_location(wrapped, node) ast.fix_missing_locations(wrapped) return wrapped
def visitwithitem(self, n, *args): cexpr = self.dispatch(n.context_expr, *args) optvars = self.dispatch(n.optional_vars, *args) if optvars: if isinstance(optvars, ast.Name): cexpr = retic_ast.Check(value=cexpr, type=optvars.retic_type, lineno=cexpr.lineno, col_offset=cexpr.col_offset) elif isinstance(target, ast.Starred): raise exc.UnimplementedException( 'Assignment checks against Starred') elif isinstance(target, ast.List): raise exc.UnimplementedException( 'Assignment checks against List') elif isinstance(target, ast.Tuple): raise exc.UnimplementedException( 'Assignment checks against Tuple') # prot = self.handlewithitem(optvars) ret = ast.withitem(context_expr=cexpr, optional_vars=optvars) # ret.retic_protector = None return ret
def compile_with_expression(self, expr): expr.pop(0) # with args = expr.pop(0) if len(args) > 2 or len(args) < 1: raise HyTypeError(expr, "with needs [arg (expr)] or [(expr)]") args.reverse() ctx = self.compile(args.pop(0)) thing = None if args != []: thing = self._storeize(self.compile(args.pop(0))) ret = ast.With(context_expr=ctx, lineno=expr.start_line, col_offset=expr.start_column, optional_vars=thing, body=self._code_branch( [self.compile(x) for x in expr], expr.start_line, expr.start_column)) if sys.version_info[0] >= 3 and sys.version_info[1] >= 3: ret.items = [ast.withitem(context_expr=ctx, optional_vars=thing)] return ret
def wrap_in_with(self, name, val, body): name_expr = ast.Str(name) val_expr = ast.Num(val) args = [name_expr, val_expr] scope_expr = ast.Call(func=ast.Name(id='scope', ctx=ast.Load()), args=args, keywords=[]) return [ast.With(items=[ast.withitem(scope_expr, None)], body=body)]
def visitwithitem(self, n, *args): cexpr = self.dispatch(n.context_expr, *args) optvars = self.dispatch(n.optional_vars, *args) prot = self.handlewithitem(optvars) ret = ast.withitem(context_expr=cexpr, optional_vars=optvars) ret.retic_protector = prot return ret
def generate(self, element:Element, GC:GenerationContext): acode = element.code context_element = acode[1] context_element_code = context_element.code assert len(context_element_code) > 0 with_items = [] with GC.let(domain=ExpressionDomain): for ctxel in context_element_code: if is_form(ctxel.code, "as"): ctxelcode = ctxel.code assert len(ctxel) == 3 ctx_expr = GC.generate(ctxelcode[1]) opt_var = GC.generate(ctxelcode[2]) with_items.append(ast.withitem(context_expr=ctx_expr, optional_vars=opt_var)) else: ctx_expr = GC.generate(ctxel) with_items.append(ast.withitem(context_expr=ctx_expr, optional_vars=None)) body_items = [] with GC.let(domain=SDom): for bodyel in acode[2:]: extend_body(body_items, GC.generate(bodyel)) return ast.With(items=with_items, body=body_items)
def generate(self, element: Element, GC: GenerationContext): acode = element.code context_element = acode[1] context_element_code = context_element.code assert len(context_element_code) > 0 with_items = [] with GC.let(domain=ExpressionDomain): for ctxel in context_element_code: if is_form(ctxel.code, "as"): ctxelcode = ctxel.code assert len(ctxel) == 3 ctx_expr = GC.generate(ctxelcode[1]) opt_var = GC.generate(ctxelcode[2]) with_items.append( ast.withitem(context_expr=ctx_expr, optional_vars=opt_var)) else: ctx_expr = GC.generate(ctxel) with_items.append( ast.withitem(context_expr=ctx_expr, optional_vars=None)) body_items = [] with GC.let(domain=SDom): for bodyel in acode[2:]: extend_body(body_items, GC.generate(bodyel)) return ast.With(items=with_items, body=body_items)
def wrap_in_outer(self, name, counter, node): #return node # <- to disable name_expr = ast.Str(name) counter_expr = ast.Num(counter) args = [name_expr, counter_expr, ast.Name(id=TaintName)] scope_expr = ast.Call(func=ast.Name(id=TaintedScope, ctx=ast.Load()), args=args, keywords=[]) return ast.With( items=[ast.withitem(scope_expr, ast.Name(id=TaintName))], body=[node])
def wrap_in_method(self, body): method_name_expr = ast.Str(methods[-1]) args = [method_name_expr] scope_expr = ast.Call(func=ast.Name(id='method__', ctx=ast.Load()), args=args, keywords=[]) return [ ast.With( items=[ast.withitem(scope_expr, ast.Name(id='_method__'))], body=body) ]
def _make_with_node(self, with_expr, body): if self.HAS_WITHITEM: return ast.With( items=[ast.withitem( context_expr=with_expr, optional_vars=None)], body=body) else: return ast.With( context_expr=with_expr, optional_vars=None, body=body)
def test_With(self): # with A: pass A = ast.Name('A', ast.Load()) A_clause = ast.withitem(A, None) with_A = ast.With([A_clause], [ast.Pass()]) self.verify(with_A, 'with A:pass') # with A as a: pass a = ast.Name('a', ast.Store()) a_clause = ast.withitem(A, a) with_a = ast.With([a_clause], [ast.Pass()]) self.verify(with_a, 'with A as a:pass') # with A as A, B: pass B = ast.Name('B', ast.Load()) B_clause = ast.withitem(B, None) with_B = ast.With([a_clause, B_clause], [ast.Pass()]) self.verify(with_B, 'with A as a,B:pass') # with A as A, B as b: pass b = ast.Name('b', ast.Store()) b_clause = ast.withitem(B, b) with_b = ast.With([a_clause, b_clause], [ast.Pass()]) self.verify(with_b, 'with A as a,B as b:pass')
def wrap_in_method(self, body, args): method_name_expr = ast.Str(methods[-1]) my_args = ast.List(args.args, ast.Load()) args = [method_name_expr, my_args] scope_expr = ast.Call(func=ast.Name(id=TaintedMethod, ctx=ast.Load()), args=args, keywords=[]) # we expect the method__ to push in the taint in the beginning, and pop out when it is done. return [ ast.With(items=[ast.withitem(scope_expr, ast.Name(id=TaintName))], body=body) ]
def make_withitem(queue, stack): """ Make an ast.withitem node. """ context_expr = make_expr(stack) # This is a POP_TOP for just "with <expr>:". # This is a STORE_NAME(name) for "with <expr> as <name>:". as_instr = queue.popleft() if isinstance(as_instr, (instrs.STORE_FAST, instrs.STORE_NAME, instrs.STORE_DEREF, instrs.STORE_GLOBAL)): return ast.withitem( context_expr=context_expr, optional_vars=make_assign_target(as_instr, queue, stack), ) elif isinstance(as_instr, instrs.POP_TOP): return ast.withitem(context_expr=context_expr, optional_vars=None) else: raise DecompilationError( "Don't know how to make withitem from %s" % as_instr, )
def make_with(): """With(withitem* items, stmt* body, string? type_comment)""" """withitem = (expr context_expr, expr? optional_vars)""" return ast.With( items=[ ast.withitem(context_expr=ast.Name(id="context_manager", ctx=ast.Load()), optional_vars=ast.Name(id="f", ctx=ast.Store())) ], body=[make_statement()], type_comment=None, )
def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.AST: with_item = ast.withitem(context_expr=ast.Call(func=ast.Name( id='SoftAssertions', ctx=ast.Load()), args=[], keywords=[]), optional_vars=ast.Name(id='ctx', ctx=ast.Store())) with_stmt = ast.With(items=[with_item], body=node.body) node.body = [with_stmt] new_node = fix_node(node) return self.generic_visit(new_node)
def wrap_in_outer(self, name, can_empty, counter, node): name_expr = ast.Str(name) can_empty_expr = ast.Str(can_empty) counter_expr = ast.Num(counter) method_id = ast.Name(id='_method__') args = [name_expr, counter_expr, method_id, can_empty_expr] scope_expr = ast.Call(func=ast.Name(id='stack__', ctx=ast.Load()), args=args, keywords=[]) return ast.With(items=[ ast.withitem(scope_expr, ast.Name(id='%s_%d_stack__' % (name, counter))) ], body=[node])
def wrap_in_inner(self, name, counter, val, body): val_expr = ast.Num(val) stack_iter = ast.Name(id='%s_%d_stack__' % (name, counter)) method_id = ast.Name(id='_method__') args = [val_expr, stack_iter, method_id] scope_expr = ast.Call(func=ast.Name(id='scope__', ctx=ast.Load()), args=args, keywords=[]) return [ ast.With(items=[ ast.withitem( scope_expr, ast.Name(id='%s_%d_%d_scope__' % (name, counter, val))) ], body=body) ]
def visit_While(self, tree_node): global while_counter while_counter += 1 test = tree_node.test body = tree_node.body assert not tree_node.orelse self.generic_visit(tree_node) name = ast.Str('while_%d %s' % (while_counter, method_name)) val = ast.Num(0) scope_expr = ast.Call(func=ast.Name(id='scope', ctx=ast.Load()), args=[name, val], keywords=[]) tree_node.body = [ ast.With(items=[ast.withitem(scope_expr, None)], body=body) ] return tree_node
def wrapwith(item, body, locref=None): """Wrap ``body`` with a single-item ``with`` block, using ``item``. ``item`` must be an expr, used as ``context_expr`` of the ``withitem`` node. ``locref`` is an optional AST node to copy source location info from. If not supplied, ``body[0]`` is used. Syntax transformer. Returns the wrapped body. """ locref = locref or body[0] wrapped = With(items=[withitem(context_expr=item, optional_vars=None)], body=body, lineno=locref.lineno, col_offset=locref.col_offset) return [wrapped]
def _rewrite_if(tree, var_name=None, **kw_args): # TODO refactor into a _rewrite_switch and a _rewrite_if """ Rewrite if statements to treat pattern matches as boolean expressions. Recall that normally a pattern match is a statement which will throw a PatternMatchException if the match fails. We can therefore use try-blocks to produce the desired branching behavior. var_name is an optional parameter used for rewriting switch statements. If present, it will transform predicates which are expressions into pattern matches. """ # with q as rewritten: # try: # with matching: # u%(matchPattern) # u%(successBody) # except PatternMatchException: # u%(_maybe_rewrite_if(failBody)) # return rewritten if not isinstance(tree, ast.If): return tree if var_name: tree.test = ast.BinOp(tree.test, ast.LShift(), ast.Name(var_name, ast.Load())) elif not (isinstance(tree.test, ast.BinOp) and \ isinstance(tree.test.op, ast.LShift)): return tree handler = ast.ExceptHandler(hq[PatternMatchException], None, tree.orelse) try_stmt = ast.Try(tree.body, [handler], [], []) macroed_match = ast.With( [ast.withitem(ast.Name('_matching', ast.Load()), None)], [ast.Expr(tree.test)]) try_stmt.body = [macroed_match] + try_stmt.body if len(handler.body) == 1: # (== tree.orelse) # Might be an elif handler.body = [_rewrite_if(handler.body[0], var_name)] elif not handler.body: handler.body = [ast.Pass()] return try_stmt
def code_visit_With(self, node): if len(node.items) != 1: raise NotImplementedError item = node.items[0] if item.optional_vars is not None: raise NotImplementedError ctxm = self.get_user_ctxm(item.context_expr) if ctxm is None: self.code_generic_visit(node) return node # user context manager self.code_generic_visit(node, {"items"}) if not hasattr(ctxm, "__enter__") or not hasattr(ctxm.__enter__, "k_function_info"): raise NotImplementedError enter = get_inline( self.core, self.attribute_namespace, self.in_use_names, None, self.mappers, ctxm.__enter__.k_function_info.k_function, [ctxm], dict(), ) if not hasattr(ctxm, "__exit__") or not hasattr(ctxm.__exit__, "k_function_info"): raise NotImplementedError exit = get_inline( self.core, self.attribute_namespace, self.in_use_names, None, self.mappers, ctxm.__exit__.k_function_info.k_function, [ctxm, None, None, None], dict(), ) try_stmt = ast.copy_location(ast.Try(body=node.body, handlers=[], orelse=[], finalbody=exit.body), node) return ast.copy_location( ast.With( items=[ast.withitem(context_expr=ast.Name(id="sequential", ctx=ast.Load()), optional_vars=None)], body=enter.body + [try_stmt], ), node, )
def visit_stmt(self, node): context_expr = _create_simple_marker_call( super(_NodeVisitor, self).generic_visit(node), TreeTracerBase._treetrace_hidden_with_stmt) if PY3: wrapped = ast.With( items=[ast.withitem(context_expr=context_expr)], body=[node], ) else: wrapped = ast.With( context_expr=context_expr, body=[node], ) ast.copy_location(wrapped, node) ast.fix_missing_locations(wrapped) return wrapped
def visit_With(self, node): change_node = False new_items = [] for item in node.items: if isinstance(item.context_expr, ast.YieldFrom): new_item = ast.withitem( item.context_expr.value, item.optional_vars, ) new_items.append(new_item) change_node = True else: new_items.append(item) if not change_node: return node return ast.AsyncWith(items=new_items, body=node.body)
def util_json_builder(self): """ Return: ast sub-tree of a function to read and parse json file: with io.open(path, mode='r', encoding='utf-8') as f: return json.loads(f.read()) """ io_open = ast_mod.Call( func=ast_mod.Attribute(value=ast_name('io'), attr=ast_name('open')), args=[ast_name('path')], keywords=[ ast_mod.keyword(arg='mode', value=ast_mod.Constant(value='r')), ast_mod.keyword(arg='encoding', value=ast_mod.Constant(value='utf-8')) ]) f_read = ast_mod.Call(ast_mod.Attribute(value=ast_name('f'), attr=ast_name('read')), args=[], keywords=[]) return_node = ast_mod.Return(value=ast_mod.Call(func=ast_mod.Attribute( value=ast_name('json'), attr=ast_name('loads')), args=[f_read], keywords=[])) body = [ ast_mod.With(items=[ ast_mod.withitem(context_expr=io_open, optional_vars=ast_name('f')) ], body=[ast_mod.Expr(value=return_node)]) ] func = ast_mod.FunctionDef(name="util_load_json", args=ast_mod.arguments( posonlyargs=[], args=[ast_name('path')], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=body, decorator_list=[], returns=None) return func
def visit_With(self, node): self.generic_visit(node) if (isinstance(node.items[0].context_expr, ast.Call) and node.items[0].context_expr.func.id == "watchdog"): idname = "__watchdog_id_" + str(self.watchdog_id_counter) self.watchdog_id_counter += 1 time = ast.BinOp(left=node.items[0].context_expr.args[0], op=ast.Mult(), right=ast.Num(1000)) time_int = ast.Call( func=ast.Name("round", ast.Load()), args=[time], keywords=[], starargs=None, kwargs=None) syscall_set = ast.Call( func=ast.Name("syscall", ast.Load()), args=[ast.Str("watchdog_set"), time_int], keywords=[], starargs=None, kwargs=None) stmt_set = ast.copy_location( ast.Assign(targets=[ast.Name(idname, ast.Store())], value=syscall_set), node) syscall_clear = ast.Call( func=ast.Name("syscall", ast.Load()), args=[ast.Str("watchdog_clear"), ast.Name(idname, ast.Load())], keywords=[], starargs=None, kwargs=None) stmt_clear = ast.copy_location(ast.Expr(syscall_clear), node) node.items[0] = ast.withitem( context_expr=ast.Name(id="sequential", ctx=ast.Load()), optional_vars=None) node.body = [ stmt_set, ast.Try(body=node.body, handlers=[], orelse=[], finalbody=[stmt_clear]) ] return node
def _create_with_scope(body, kwargs): ''' Helper function to wrap a block in a scope stack: with ContextScope(context, **kwargs) as context: ... body ... ''' return ast.With( items=[ ast.withitem( context_expr=_a.Call( _a.Name('ContextScope'), [_a.Name('context')], keywords=kwargs, ), optional_vars=_a.Name('context', ctx=ast.Store()) ), ], body=body, )
def compile_with_as_expression(self, expr): expr.pop(0) # with-as ctx = self.compile(expr.pop(0)) thing = self.compile(expr.pop(0)) if isinstance(thing, ast.Tuple): for x in thing.elts: x.ctx = ast.Store() thing.ctx = ast.Store() ret = ast.With(context_expr=ctx, lineno=expr.start_line, col_offset=expr.start_column, optional_vars=thing, body=self._mangle_branch([ self.compile(x) for x in expr])) if sys.version_info[0] >= 3 and sys.version_info[1] >= 3: ret.items = [ast.withitem(context_expr=ctx, optional_vars=thing)] return ret
def code_visit_Call(self, node): func = self.static_visit(node.func) node.args = [self.code_visit(arg) for arg in node.args] for kw in node.keywords: kw.value = self.code_visit(kw.value) if is_embeddable(func): node.func = ast.copy_location( ast.Name(func.__name__, ast.Load()), node) return node elif is_inlinable(self.core, func): retval_name = func.k_function_info.k_function.__name__ + "_return" retval_name_m = new_mangled_name(self.in_use_names, retval_name) args = [func.__self__] + node.args kwargs = {kw.arg: kw.value for kw in node.keywords} inlined = get_inline(self.core, self.attribute_namespace, self.in_use_names, retval_name_m, self.mappers, func.k_function_info.k_function, args, kwargs) seq = ast.copy_location( ast.With( items=[ast.withitem(context_expr=ast.Name(id="sequential", ctx=ast.Load()), optional_vars=None)], body=inlined.body), node) self._insertion_point.append(seq) return ast.copy_location(ast.Name(retval_name_m, ast.Load()), node) else: arg1 = ast.copy_location(ast.Str("rpc"), node) arg2 = ast.copy_location( value_to_ast(self.mappers.rpc.encode(func)), node) node.args[0:0] = [arg1, arg2] node.func = ast.copy_location( ast.Name("syscall", ast.Load()), node) return node
def code_visit_With(self, node): if len(node.items) != 1: raise NotImplementedError item = node.items[0] if item.optional_vars is not None: raise NotImplementedError ctxm = self.get_user_ctxm(item.context_expr) if ctxm is None: self.code_generic_visit(node) return node # user context manager self.code_generic_visit(node, {"items"}) if (not hasattr(ctxm, "__enter__") or not hasattr(ctxm.__enter__, "k_function_info")): raise NotImplementedError enter = get_inline(self.core, self.attribute_namespace, self.in_use_names, None, self.mappers, ctxm.__enter__.k_function_info.k_function, [ctxm], dict()) if (not hasattr(ctxm, "__exit__") or not hasattr(ctxm.__exit__, "k_function_info")): raise NotImplementedError exit = get_inline(self.core, self.attribute_namespace, self.in_use_names, None, self.mappers, ctxm.__exit__.k_function_info.k_function, [ctxm, None, None, None], dict()) try_stmt = ast.copy_location( ast.Try(body=node.body, handlers=[], orelse=[], finalbody=exit.body), node) return ast.copy_location( ast.With(items=[ ast.withitem(context_expr=ast.Name(id="sequential", ctx=ast.Load()), optional_vars=None) ], body=enter.body + [try_stmt]), node)
def r_with(node: ast.Subscript, ctx: Context, clauses: list, rule_id): ctx.assert_clause_num_at_most(clauses, 1) with_clause = clauses[0] ctx.assert_head(with_clause) items = [] for arg in with_clause.head: context_expr, var = check_as(ctx, arg, COMPARATORS[aliases.As]) item = ast.withitem( context_expr=ctx.compile(context_expr), optional_vars=var, ) items.append(copy_lineinfo(arg, item)) return copy_lineinfo( node, rule_id( items=items, body=_compile_stmts(ctx, with_clause.body), ), )
def _create_with_scope(body, kwargs): ''' Helper function to wrap a block in a scope stack: with ContextScope(context, **kwargs) as context: ... body ... ''' return ast.With( items=[ ast.withitem( context_expr=ast.Call( func=ast.Name(id='ContextScope', ctx=ast.Load()), args=[ ast.Name(id='context', ctx=ast.Load()), ], keywords=kwargs, starargs=None, kwargs=None ), optional_vars=ast.Name(id='context', ctx=ast.Store()) ), ], body=body, )
def visitwithitem(self, n, *args): cexpr = self.dispatch(n.context_expr, *args) optvars = self.dispatch(n.optional_vars, *args) if optvars: if isinstance(optvars, ast.Name): cexpr = retic_ast.Check(value=cexpr, type=optvars.retic_type, lineno=cexpr.lineno, col_offset=cexpr.col_offset) elif isinstance(target, ast.Starred): raise exc.UnimplementedException('Assignment checks against Starred') elif isinstance(target, ast.List): raise exc.UnimplementedException('Assignment checks against List') elif isinstance(target, ast.Tuple): raise exc.UnimplementedException('Assignment checks against Tuple') # prot = self.handlewithitem(optvars) ret = ast.withitem(context_expr=cexpr, optional_vars=optvars) # ret.retic_protector = None return ret
def section_stmt_action(s, loc, tokens): body = tokens[1][:] if PY3: return ast.With(items=[ ast.withitem(context_expr=ast.Call(func=ast.Name(id='_section', ctx=ast.Load()), args=[tokens[0]], keywords=[], starargs=None, kwargs=None), optional_vars=None) ], body=body) else: return ast.With(context_expr=ast.Call(func=ast.Name(id='_section', ctx=ast.Load()), args=[tokens[0]], keywords=[], starargs=None, kwargs=None), optional_vars=None, body=body)
def with_(self, item, body): return ast.With( items=[ast.withitem(context_expr=to_ast(item))], body=to_stmt_list(body))
def visit_If(self, node): lineno = node.lineno col_offset = node.col_offset if_test = node.test if_body = node.body else_body = node.orelse test_call = ast.Call(lineno=lineno, col_offset=col_offset, func=ast.Name( lineno=lineno, col_offset=col_offset, id='__combra_if_else__' if else_body else '__combra_if__', ctx=ast.Load()), args=[if_test], keywords=[]) control_call = ast.Expr(lineno=lineno, col_offset=col_offset, value=ast.Call(lineno=lineno, col_offset=col_offset, func=ast.Name(lineno=lineno, col_offset=col_offset, id='__combra_control__', ctx=ast.Load()), args=[], keywords=[])) if_body.insert(0, control_call) withnode = ast.With(lineno=lineno, col_offset=col_offset, items = [ast.withitem( context_expr=test_call, optional_vars=None)], body=if_body) self.visit(withnode) if not else_body: return withnode # else body -> new with node test_call_else = ast.Call(lineno=lineno, col_offset=col_offset, func=ast.Name(lineno=lineno, col_offset=col_offset, id='__combra_else__', ctx=ast.Load()), args=[], keywords=[]) else_control_call = ast.Expr(lineno=lineno, col_offset=col_offset, value=ast.Call(lineno=lineno, col_offset=col_offset, func=ast.Name( lineno=lineno, col_offset=col_offset, id='__combra_control__', ctx=ast.Load()), args=[], keywords=[])) else_body.insert(0, else_control_call) withnode_else = ast.With(lineno=lineno, col_offset=col_offset, items = [ast.withitem( context_expr=test_call_else, optional_vars=None)], body=else_body) self.visit(withnode_else) return [withnode, withnode_else]
def visitwithitem(self, n, *args): return ast.withitem(context_expr=self.dispatch(n.context_expr, *args), optional_vars=(self.dispatch(n.optional_vars, *args) if n.optional_vars else None))