def after_stmt(self, node, frame, exc_value, exc_traceback): if frame.f_code not in self._code_infos: return frame_info = self.stack[frame] expression_stack = frame_info.expression_stack if expression_stack: while isinstance(expression_stack[-1], self.SPECIAL_COMPREHENSION_TYPES): inner_frame = frame_info.comprehension_frames[expression_stack[-1]] expression_stack = self.stack[inner_frame].expression_stack self._set_node_value( expression_stack[-1], frame, [exception_string(exc_value), -1])
def exit_call(self, exit_info): frame = exit_info.current_frame if frame.f_code not in self._code_infos: return frame_info = self.stack[frame] top_iteration = frame_info.iteration loop_iterations = top_iteration.extract_iterations()['loops'] node_values = _deep_dict() def extract_values(iteration, path): for k, v in iteration.vals.items(): full_path = (k,) + path d = node_values for path_k in full_path[:-1]: d = d[path_k] d[full_path[-1]] = v for loop in iteration.loops.values(): for i, iteration in enumerate(loop): extract_values(iteration, path + (i,)) extract_values(top_iteration, ()) db_func = self._code_infos[frame.f_code].db_func exc = exit_info.exc_value if exc: traceback_str = ''.join(traceback.format_exception(type(exc), exc, exit_info.exc_tb)) exception = exception_string(exc) else: traceback_str = exception = None call = Call(id=frame_info.call_id, function=db_func, arguments=frame_info.arguments, return_value=cheap_repr(exit_info.return_value), exception=exception, traceback=traceback_str, data=json.dumps( dict( node_values=node_values, loop_iterations=loop_iterations, type_names=type_registry.names(), num_special_types=type_registry.num_special_types, ), separators=(',', ':') ), start_time=frame_info.start_time) session.add(call) session.commit()