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 __call__(self, target, engine): remaining = self.expression assignments = [] while remaining: if self.ignore_prefix and match_prefix(remaining) is not None: compiler = engine.parse(remaining) assignment = compiler.assign_value(target) remaining = "" else: for m in split_parts.finditer(remaining): expression = remaining[:m.start()] remaining = remaining[m.end():] break else: expression = remaining remaining = "" expression = expression.replace('\\|', '|') assignment = self.translate_proxy(engine, expression, target) assignments.append(assignment) if not assignments: if not remaining: raise ExpressionError("No input:", remaining) assignments.append(self.translate_proxy(engine, remaining, target)) for i, assignment in enumerate(reversed(assignments)): if i == 0: body = assignment else: body = [ TryExcept( body=assignment, handlers=[ ast.ExceptHandler( type=ast.Tuple(elts=map( resolve_global, self.exceptions), ctx=ast.Load()), name=None, body=body if exc_clear is None else body + [ ast.Expr( ast.Call( func=load("__exc_clear"), args=[], keywords=[], starargs=None, kwargs=None, )) ], ) ], ) ] return body
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 __call__(self, target, engine): ignore = store("_ignore") compiler = engine.parse(self.expression, False) body = compiler.assign_value(ignore) classes = map(resolve_global, self.exceptions) return [ TryExcept( body=body, handlers=[ast.ExceptHandler( type=ast.Tuple(elts=classes, ctx=ast.Load()), name=None, body=template("target = 0", target=target), )], orelse=template("target = 1", target=target) ) ]
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 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)) if new_node.args.vararg is not None: new_node.body.append( self._trace_assignment(new_node.args.vararg, node.lineno)) if new_node.args.kwarg is not None: new_node.body.append( self._trace_assignment(new_node.args.kwarg, node.lineno)) if try_body: 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