def visit_Assert(self, node): # Converts assert statements into try-except-finally blocks that increment the relevant counters try_except_block = self.create_try_except_block(node) finally_block = self.create_finally_block(node) new_node = ast.TryFinally(body=try_except_block, finalbody=finally_block, nl=True) ast.fix_missing_locations(new_node) return new_node
def visitWith(self, node): i = self.withcnt() abc, exc = 'WiTh_CoNtExT__%i' % i, 'WiTh_ExC__%i' % i lno = node.lineno self.visit(node.expr) self.visit(node.code) rbc = hasRBC(node.code) stmts = [] stmts.append( ast_Assign(abc, ast.CallFunc(ast.Getattr(node.expr, '__context__'), []))) if rbc: stmts.append(ast_Assign(exc, ast.Const((None, None, None)))) enter = ast.CallFunc(ast_Getattr(abc, '__enter__'), []) if node.var: enter = ast_Assign(node.var, enter) else: enter = ast.Discard(enter) stmts.append(enter) if rbc: stmts.append( ast.TryFinally( ast.TryExcept( node.code, [(None, None, ast.Stmt([ ast_Assign( exc, ast.CallFunc(ast_Getattr('sys', 'exc_info'), [])), ast.Raise(None, None, None, lno) ]))], None, lno), ast.Discard( ast.CallFunc(ast_Getattr(abc, '__exit__'), [], ast.Name(exc, 0))), lno)) else: stmts.append( ast.TryExcept( node.code, [(None, None, ast.Stmt([ ast.Discard( ast.CallFunc( ast_Getattr(abc, '__exit__'), [], ast.CallFunc(ast_Getattr('sys', 'exc_info'), []))), ast.Raise(None, None, None, lno) ]))], ast.Stmt([ ast.Discard( ast.CallFunc(ast_Getattr(abc, '__exit__'), 3 * [ast.Const(None)])) ]), lno)) make_copy(node, ast.Stmt(stmts))
def visit_Try(self, node): if node.finalbody: new_node = ast.TryFinally(self._visit(node.body), self._visit(node.finalbody)) else: new_node = ast.TryExcept( self._visit(node.body), self._visit(node.handlers), self._visit(node.orelse), ) ast.copy_location(new_node, node) return new_node
def psilc(p): tree = build_ast(p) def dump(node, depth): print(" "*depth, node, sep="") for x in ast.iter_child_nodes(node): dump(x, depth+1) #print("ast:") #dump(tree, 0) lift = LiftLambda() tree = lift.visit(tree) if lift.lifted: return ast.TryFinally(lift.lifted + [make_stmt(tree)], []) else: return make_stmt(tree)
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 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 gen_unpack_wrapper(self, node, target, ctx='store'): """Helper function to protect tuple unpacks. node: used to copy the locations for the new nodes. target: is the tuple which must be protected. ctx: Defines the context of the returned temporary node. It returns a tuple with two element. Element 1: Is a temporary name node which must be used to replace the target. The context (store, param) is defined by the 'ctx' parameter.. Element 2: Is a try .. finally where the body performs the protected tuple unpack of the temporary variable into the original target. """ # Generate a tmp name to replace the tuple with. tmp_name = self.gen_tmp_name() # Generates an expressions which protects the unpack. # converter looks like 'wrapper(tmp_name)'. # 'wrapper' takes care to protect sequence unpacking with _getiter_. converter = self.protect_unpack_sequence( target, ast.Name(tmp_name, ast.Load())) # Assign the expression to the original names. # Cleanup the temporary variable. # Generates: # try: # # converter is 'wrapper(tmp_name)' # arg = converter # finally: # del tmp_arg try_body = [ast.Assign(targets=[target], value=converter)] finalbody = [self.gen_del_stmt(tmp_name)] if IS_PY2: cleanup = ast.TryFinally(body=try_body, finalbody=finalbody) else: cleanup = ast.Try(body=try_body, finalbody=finalbody, handlers=[], orelse=[]) if ctx == 'store': ctx = ast.Store() elif ctx == 'param': ctx = ast.Param() else: # pragma: no cover # Only store and param are defined ctx. raise NotImplementedError( 'Unsupported context type: "{name}".'.format(name=type(ctx)), ) # This node is used to catch the tuple in a tmp variable. tmp_target = ast.Name(tmp_name, ctx) copy_locations(tmp_target, node) copy_locations(cleanup, node) return (tmp_target, cleanup)
def visit_With(self, node): node = self.generic_visit(node) # Build equivalent code with try catch finally. # PEP-0343 provides the equivalent code for us. statements = [] # mgr = node.expr mgr_id = self.id_factory("mgr") s = mk_assign(mgr_id, node.context_expr) statements.append(s) # exit = type(msg).__exit__ exit_id = self.id_factory("exit") s = mk_assign(exit_id, mk_attr(mk_call('type', [mk_name(mgr_id)]), "__exit__")) statements.append(s) # value = type(msg).__enter__(mgr) value_id = self.id_factory("value") s = mk_assign( value_id, mk_call_expr( mk_attr(mk_call('type', [mk_name(mgr_id)]), "__enter__"), [mk_name(mgr_id)])) statements.append(s) # exc = True exc_id = self.id_factory("exc") s = mk_assign(exc_id, mk_name("True")) statements.append(s) # try: tryfinally_body = [] tryfinally_finalbody = [] s = ast.TryFinally(body=tryfinally_body, finalbody=tryfinally_finalbody) statements.append(s) # try: tryexcept_body = [] tryexcept_except = [] expt_handler = ast.ExceptHandler(type=None, name=None, body=tryexcept_except) s = ast.TryExcept(body=tryexcept_body, handlers=[expt_handler], orelse=[]) tryfinally_body.append(s) # node.optional_vars = value if node.optional_vars: s = ast.Assign(targets=[node.optional_vars], value=mk_name(value_id)) tryexcept_body.append(s) # body tryexcept_body.extend(node.body) # except: # exc = False s = mk_assign(exc_id, mk_name("False")) tryexcept_except.append(s) # sys.exc_info() sys_exc_info = mk_call_expr(mk_attr(mk_name('sys'), "exc_info"), []) # exit(mgr, *sys.exc_info()) exit_call = mk_call(exit_id, [mk_name(mgr_id)], vararg=sys_exc_info) # not exit(mgr, *sys.exc_info()) test = ast.UnaryOp(op=ast.Not(), operand=exit_call) # if not exit(mgr, *sys.exc_info()): # raise s = ast.If(test=test, body=[ast.Raise(type=None, inst=None, tback=None)], orelse=[]) tryexcept_except.append(s) # finally: # if exc: # exit(mgr, None, None, None) exit_call = mk_call(exit_id, [ mk_name(mgr_id), mk_name("None"), mk_name("None"), mk_name("None") ]) s = ast.If(test=mk_name(exc_id), body=[ast.Expr(value=exit_call)], orelse=[]) tryfinally_finalbody.append(s) return statements
def visitTryFinally(self, n, *args): body = self.dispatch_statements(n.body, *args) finalbody = self.dispatch_statements(n.finalbody, *args) return ast.TryFinally(body, finalbody)
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 compile_try_expression(self, expr): expr.pop(0) # try try: body = expr.pop(0) except IndexError: body = [] # (try something…) body = self._code_branch(self.compile(body), expr.start_line, expr.start_column) orelse = [] finalbody = [] handlers = [] for e in expr: if not len(e): raise HyTypeError(e, "Empty list not allowed in `try'") if e[0] in (HySymbol("except"), HySymbol("catch")): handlers.append(self.compile(e)) elif e[0] == HySymbol("else"): if orelse: raise HyTypeError( e, "`try' cannot have more than one `else'") else: orelse = self._code_branch(self.compile(e[1:]), e.start_line, e.start_column) elif e[0] == HySymbol("finally"): if finalbody: raise HyTypeError( e, "`try' cannot have more than one `finally'") else: finalbody = self._code_branch(self.compile(e[1:]), e.start_line, e.start_column) else: raise HyTypeError(e, "Unknown expression in `try'") # Using (else) without (except) is verboten! if orelse and not handlers: raise HyTypeError(e, "`try' cannot have `else' without `except'") # (try) or (try BODY) # Generate a default handler for Python >= 3.3 and pypy if not handlers and not finalbody and not orelse: handlers = [ ast.ExceptHandler(lineno=expr.start_line, col_offset=expr.start_column, type=None, name=None, body=[ ast.Pass(lineno=expr.start_line, col_offset=expr.start_column) ]) ] if sys.version_info[0] >= 3 and sys.version_info[1] >= 3: # Python 3.3 features a merge of TryExcept+TryFinally into Try. return ast.Try(lineno=expr.start_line, col_offset=expr.start_column, body=body, handlers=handlers, orelse=orelse, finalbody=finalbody) if finalbody: if handlers: return ast.TryFinally(lineno=expr.start_line, col_offset=expr.start_column, body=[ ast.TryExcept( lineno=expr.start_line, col_offset=expr.start_column, handlers=handlers, body=body, orelse=orelse) ], finalbody=finalbody) return ast.TryFinally(lineno=expr.start_line, col_offset=expr.start_column, body=body, finalbody=finalbody) return ast.TryExcept(lineno=expr.start_line, col_offset=expr.start_column, handlers=handlers, body=body, orelse=orelse)