def __setattr__(self, name, value): if type(value) is dict: value = copy(value) for k, v in value.items(): value[k] = encode(v) super.__setattr__(self, name, value)
def interaction(self, frame, traceback, event_type): self.setup(frame, traceback) tos = self.stack[self.curindex] func_name = tos[0].f_code.co_name lineno = tos[1] where = frame.f_code.co_filename if where != '<string>': # this is not a user code frame return # so just skip it if func_name in ('<listcomp>', '<genexpr>') and event_type != 'step_line': return # skip step line in generator and list comprehensions - they're useless # each element is a pair of (function name, locals dict) stack_locals = [] # climb up until you find '<module>', which is (hopefully) the global scope i = self.curindex while True: cur_frame = self.stack[i][0] where = cur_frame.f_code.co_name if where == '<module>': break # special case for lambdas - grab their line numbers too if where == '<lambda>': where = 'lambda on line ' + str(cur_frame.f_code.co_firstlineno) elif where == '': where = 'unnamed function' this_locals = self._filter_variables(cur_frame.f_locals, ('__return__')) # filter some internal variables # (they're useless and JSON-danger) # in the list comprehensions and generators if where in ('<listcomp>', '<genexpr>'): varnames = list(this_locals.keys()) for name in varnames: if name.startswith('.'): del this_locals[name] for name, value in this_locals.items(): this_locals[name] = encode(value) stack_locals.append((where, this_locals)) i -= 1 trace_entry = TraceEntry( event = event_type, line = lineno, func_name = func_name, globals = self._filter_variables(tos[0].f_globals), stack_locals = stack_locals, stdout = self.stdout.getvalue(), stderr = self.stderr.getvalue(), ) # if there's an exception, then record its info: if event_type == 'exception': # always check in f_locals exc_type, exc_value = frame.f_locals['__exception__'] self._exception = parse_exception((exc_type, exc_value, traceback)) trace_entry.__dict__.update(self._exception) self.trace.append(trace_entry) if len(self.trace) >= MAX_EXECUTED_LINES: self.trace.append(TraceEntry(event='instruction_limit_reached', exception_msg='Stopped after ' + str(MAX_EXECUTED_LINES) + ' steps to prevent possible infinite loop')) self.force_terminate() self.forget()
def interaction(self, frame, traceback, event_type): self.setup(frame, traceback) tos = self.stack[self.curindex] func_name = tos[0].f_code.co_name lineno = tos[1] where = frame.f_code.co_filename if where != '<string>': # this is not a user code frame return # so just skip it if func_name in ('<listcomp>', '<genexpr>') and event_type != 'step_line': return # skip step line in generator and list comprehensions - they're useless # each element is a pair of (function name, locals dict) stack_locals = [] # climb up until you find '<module>', which is (hopefully) the global scope i = self.curindex while True: cur_frame = self.stack[i][0] where = cur_frame.f_code.co_name if where == '<module>': break # special case for lambdas - grab their line numbers too if where == '<lambda>': where = 'lambda on line ' + str( cur_frame.f_code.co_firstlineno) elif where == '': where = 'unnamed function' this_locals = self._filter_variables(cur_frame.f_locals, ('__return__')) # filter some internal variables # (they're useless and JSON-danger) # in the list comprehensions and generators if where in ('<listcomp>', '<genexpr>'): varnames = list(this_locals.keys()) for name in varnames: if name.startswith('.'): del this_locals[name] for name, value in this_locals.items(): this_locals[name] = encode(value) stack_locals.append((where, this_locals)) i -= 1 trace_entry = TraceEntry( event=event_type, line=lineno, func_name=func_name, globals=self._filter_variables(tos[0].f_globals), stack_locals=stack_locals, stdout=self.stdout.getvalue(), stderr=self.stderr.getvalue(), ) # if there's an exception, then record its info: if event_type == 'exception': # always check in f_locals exc_type, exc_value = frame.f_locals['__exception__'] self._exception = parse_exception((exc_type, exc_value, traceback)) trace_entry.__dict__.update(self._exception) self.trace.append(trace_entry) if len(self.trace) >= MAX_EXECUTED_LINES: self.trace.append( TraceEntry(event='instruction_limit_reached', exception_msg='Stopped after ' + str(MAX_EXECUTED_LINES) + ' steps to prevent possible infinite loop')) self.force_terminate() self.forget()