def visit_Module(self, node): new_node = self.generic_visit(node) line_numbers = set() new_body = [] try_body = new_node.body if try_body: while try_body and self._is_module_header(try_body[0]): # noinspection PyUnresolvedReferences new_body.append(try_body.pop(0)) find_line_numbers(new_node, line_numbers) if line_numbers: first_line_number = min(line_numbers) last_line_number = max(line_numbers) handler_body = [self._create_context_call('exception'), Raise()] handler = ExceptHandler(body=handler_body, lineno=last_line_number) new_body.append(Try(body=try_body, handlers=[handler], orelse=[], finalbody=[])) new_node.body = new_body self._set_statement_line_numbers(try_body, first_line_number) self._set_statement_line_numbers(handler_body, last_line_number) return new_node
def visit_Module(self, node): new_node = self.generic_visit(node) try_body = new_node.body if try_body: new_body = [] while try_body and self._is_module_header(try_body[0]): new_body.append(try_body.pop(0)) line_numbers = set() self._find_line_numbers(new_node, line_numbers) if line_numbers: first_line_number = min(line_numbers) last_line_number = max(line_numbers) else: first_line_number = last_line_number = 1 handler_body = [self._create_context_call('exception')] handler = ExceptHandler(body=handler_body, lineno=last_line_number) new_body.append(TryExcept(body=try_body, handlers=[handler], orelse=[], finalbody=[])) new_node.body = new_body self._set_statement_line_numbers(try_body, first_line_number) self._set_statement_line_numbers(handler_body, last_line_number) return new_node
def visit_ExceptHandler(self, node: ExceptHandler) -> ExceptHandler: """ The "as" alias in `except Exception as name`. """ if node.name: node.name = self.add_placeholder(node.name) self.generic_visit(node) return node
def visit_FunctionDef(self, node): """ Instrument a function definition by creating a new report builder for this stack frame and putting it in a local variable. The local variable has the same name as the global variable so all calls can use the same CONTEXT_NAME symbol, but it means that I had to use this: x = globals()['x'].start_frame() Kind of ugly, but I think it was worth it to handle recursive calls. """ if node.name == '__repr__': return node new_node = self.generic_visit(node) line_numbers = set() self._find_line_numbers(new_node, line_numbers) first_line_number = min(line_numbers) last_line_number = max(line_numbers) args = [Num(n=first_line_number), Num(n=last_line_number)] try_body = new_node.body globals_call = Call(func=Name(id='globals', ctx=Load()), args=[], keywords=[], starargs=None, kwargs=None) global_context = Subscript(value=globals_call, slice=Index(value=Str(s=CONTEXT_NAME)), ctx=Load()) start_frame_call = Call(func=Attribute(value=global_context, attr='start_frame', ctx=Load()), args=args, keywords=[], starargs=None, kwargs=None) context_assign = Assign(targets=[Name(id=CONTEXT_NAME, ctx=Store())], value=start_frame_call) new_node.body = [context_assign] # trace function parameter values for target in new_node.args.args: if isinstance(target, Name) and target.id == 'self': continue if arg and isinstance(target, arg) and target.arg == 'self': continue new_node.body.append(self._trace_assignment(target, node.lineno)) handler_body = [self._create_context_call('exception'), Raise()] new_node.body.append( TryExcept(body=try_body, handlers=[ExceptHandler(body=handler_body)], orelse=[], finalbody=[])) self._set_statement_line_numbers(try_body, first_line_number) self._set_statement_line_numbers(handler_body, last_line_number) return new_node
def annotate_runtime_errors(self, body, imnode): from piglet.astutil import TryExcept from ast import ExceptHandler if imnode.pos is None: raise ValueError("pos attribute not set on im node") position = self.filename, imnode.pos.line handler = parse_and_strip( 'getattr(__piglet_rtdata, "context", [{{}}])[-1]' '.setdefault("__piglet_exc_locations", []).append(({!r}, {!r}))\n' 'raise\n' .format(*position)) if not isinstance(body, list): body = [body] te = TryExcept(body=body, handlers=[ExceptHandler(type=LoadName('Exception'), name=None, body=handler)]) te.position = self.filename, imnode.pos.line return te
def visit_Module(self, node): new_node = self.generic_visit(node) line_numbers = set() self._find_line_numbers(new_node, line_numbers) if line_numbers: first_line_number = min(line_numbers) last_line_number = max(line_numbers) else: first_line_number = last_line_number = 1 try_body = new_node.body handler_body = [self._create_context_call('exception')] handler = ExceptHandler(body=handler_body, lineno=last_line_number) if not try_body: # empty module new_node.body = try_body else: new_node.body = [ Try(body=try_body, handlers=[handler], orelse=[], finalbody=[]) ] self._set_statement_line_numbers(try_body, first_line_number) self._set_statement_line_numbers(handler_body, last_line_number) return new_node
def visit_FunctionDef(self, node): """ Instrument a function definition by creating a new report builder for this stack frame and putting it in a local variable. The local variable has the same name as the global variable so all calls can use the same CONTEXT_NAME symbol, but it means that I had to use this: x = globals()['x'].start_frame() Kind of ugly, but I think it was worth it to handle recursive calls. """ new_node = self.generic_visit(node) line_numbers = set() find_line_numbers(new_node, line_numbers) first_line_number = min(line_numbers) last_line_number = max(line_numbers) args = [Num(n=first_line_number), Num(n=last_line_number)] start_frame_keywords = [] for decorator in new_node.decorator_list: if getattr(decorator, 'id', None) == 'traced': start_frame_keywords.append( keyword(arg='is_decorated', value=Name(id='True', ctx=Load()))) try_body = new_node.body globals_call = Call(func=Name(id='globals', ctx=Load()), args=[], keywords=[], starargs=None, kwargs=None) global_context = Subscript(value=globals_call, slice=Index(value=Str(s=CONTEXT_NAME)), ctx=Load()) start_frame_call = Call(func=Attribute(value=global_context, attr='start_frame', ctx=Load()), args=args, keywords=start_frame_keywords, starargs=None, kwargs=None) context_assign = Assign(targets=[Name(id=CONTEXT_NAME, ctx=Store())], value=start_frame_call) new_node.body = [context_assign] if isinstance(try_body[0], Expr) and isinstance( try_body[0].value, Str): # Move docstring back to top of function. # noinspection PyUnresolvedReferences new_node.body.insert(0, try_body.pop(0)) # trace function parameter values arg_nodes = [] arg_nodes.extend(getattr(new_node.args, 'posonlyargs', [])) arg_nodes.extend(new_node.args.args) arg_nodes.append(new_node.args.kwarg) arg_nodes.append(new_node.args.vararg) arg_nodes.extend(new_node.args.kwonlyargs) for target in arg_nodes: if target is None: continue if isinstance(target, Name) and target.id == 'self': continue if isinstance(target, arg) and target.arg == 'self': continue new_node.body.append(self._trace_assignment(target, node.lineno)) if try_body: handler_body = [self._create_context_call('exception'), Raise()] new_node.body.append( Try(body=try_body, handlers=[ExceptHandler(body=handler_body)], orelse=[], finalbody=[])) self._set_statement_line_numbers(try_body, first_line_number) self._set_statement_line_numbers(handler_body, last_line_number) return new_node
def empty_script_tree(project_id: str, add_main_loop: bool = True) -> Module: """Creates barebones of the script (empty 'main' function). Returns ------- """ main_body: List[stmt] = [ Assign( targets=[Name(id="aps", ctx=Store())], value=Call(func=Name(id="ActionPoints", ctx=Load()), args=[Name(id="res", ctx=Load())], keywords=[]), type_comment=None, ) ] if add_main_loop: main_body.append( While(test=NameConstant(value=True, kind=None), body=[Pass()], orelse=[])) else: """put there "pass" in order to make code valid even if there is no other statement (e.g. no object from resources)""" main_body.append(Pass()) # TODO helper function for try ... except tree = Module( body=[ FunctionDef( name="main", args=arguments( args=[ arg(arg="res", annotation=Name(id=RES_CLS, ctx=Load()), type_comment=None) ], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[], ), body=main_body, decorator_list=[], returns=NameConstant(value=None, kind=None), type_comment=None, ), If( test=Compare(left=Name(id="__name__", ctx=Load()), ops=[Eq()], comparators=[Str(s="__main__", kind="")]), body=[ Try( body=[ With( items=[ withitem( context_expr=Call( func=Name(id=RES_CLS, ctx=Load()), args=[Str(s=project_id, kind="")], keywords=[], ), optional_vars=Name(id="res", ctx=Store()), ) ], body=[ Expr(value=Call( func=Name(id="main", ctx=Load()), args=[Name(id="res", ctx=Load())], keywords=[], )) ], type_comment=None, ) ], handlers=[ ExceptHandler( type=Name(id=Exception.__name__, ctx=Load()), name="e", body=[ Expr(value=Call( func=Name(id=arcor2.exceptions.runtime. print_exception.__name__, ctx=Load()), args=[Name(id="e", ctx=Load())], keywords=[], )) ], ) ], orelse=[], finalbody=[], ) ], orelse=[], ), ], type_ignores=[], ) add_import(tree, arcor2.exceptions.runtime.__name__, arcor2.exceptions.runtime.print_exception.__name__) add_import(tree, RES_MODULE, RES_CLS, try_to_import=False) add_import(tree, "action_points", "ActionPoints", try_to_import=False) return tree
def visit_except_handler(self, node: ast.ExceptHandler): _ = self.mapping.get(node.name) if _: node.name = _