def test_progn_raises(self, name, src, exc): """ Tests the results of progn calls that raise exceptions. Some are exceptions in the code, some are because they are invalid progn calls. """ with self.assertRaises(exc): progn(src)
def test_progn_in_frame(self, name, src, assertion): """ Tests that passing in a stackframe causes progn to evaluate code in the new context. Also asserts that implementation details do not leak out. """ stackframe = FakeFrame({'local': 'lvar'}, {'global_': 'gvar'}) progn(src, stackframe=stackframe) assertion(self, stackframe) # Make sure the register function name didn't persist. self.assertEqual(['__builtins__', 'global_'], stackframe.f_globals.keys())
def test_progn_in_frame(self, name, src, assertion): """ Tests that passing in a stackframe causes progn to evaluate code in the new context. Also asserts that implementation details do not leak out. """ stackframe = FakeFrame({'local': 'lvar'}, {'global_': 'gvar'}) progn(src, stackframe=stackframe) assertion(self, stackframe) # Make sure the register function name didn't persist. self.assertEqual( sorted(('__builtins__', 'global_')), sorted(keys(stackframe.f_globals)), )
def test_progn_uses_custom_eval_fn(self): """ Assert that the progn function uses custom eval functions properly. """ eval_fn = MagicMock() try: progn('2 + 2', eval_fn=eval_fn) except QdbPrognEndsInStatement: # This is the error that we are getting because our eval function # is not storing any results. pass calls = eval_fn.call_args_list self.assertEqual(len(calls), 1) call_args = calls[0][0] # This is constructed inside the function, but should be a module. self.assertIsInstance(call_args[0], ast.Module) self.assertEqual(call_args[1], sys._getframe()) self.assertEqual(call_args[2], 'exec')
def test_progn_uses_custom_eval_fn(self): """ Assert that the progn function uses custom eval functions properly. """ eval_fn = mock.MagicMock() try: progn('2 + 2', eval_fn=eval_fn) except QdbPrognEndsInStatement: # This is the error that we are getting because our eval function # is not storing any results. pass calls = eval_fn.call_args_list self.assertEqual(len(calls), 1) call_args = calls[0][0] # This is constructed inside the function, but should be a module. self.assertIsInstance(call_args[0], ast.Module) self.assertEqual(call_args[1], sys._getframe()) self.assertEqual(call_args[2], 'exec')
def command_eval(self, payload): """ Evaluates and expression in self.tracer.curframe, reevaluates the watchlist, and defers to user control. """ if not self.payload_check(payload, 'eval'): return self.next_command() with capture_output() as (out, err), \ self.tracer._new_execution_timeout(payload), \ self.tracer.inject_default_namespace() as stackframe: try: if self.tracer.repr_fn: # Do some some custom single mode magic that lets us call # the repr function on the last expr. try: print self.tracer.repr_fn( progn( payload, self.tracer.eval_fn, stackframe, ) ) except QdbPrognEndsInStatement: # Statements have no value to print. pass else: self.tracer.eval_fn( payload, stackframe, 'single', ) except Exception as e: self.send_print( payload, type(e).__name__, self.tracer.exception_serializer(e) ) else: out_msg = out.getvalue()[:-1] if out.getvalue() \ and out.getvalue()[-1] == '\n' else out.getvalue() self.send_print(payload, None, out_msg) self.tracer.update_watchlist() self.send_watchlist() self.next_command()
def test_progn_default(self, name, src, expected_value): """ Asserts that progn returns the last expression is various snippets of code. These should all be valid progn calls and return a value. """ f = lambda n='': 'f%s' % n # NOQA class c(object): """ Testing context manager. """ def __enter__(self): return 'c' def __exit__(self, *args, **kwargs): pass self.assertEqual(progn(src), expected_value)
def eval_(self, code, pprint=False): repr_fn = self.repr_fn outexc = None outmsg = None with capture_output() as (out, err), \ self._new_execution_timeout(code), \ self.inject_default_namespace() as stackframe: try: if not repr_fn and not pprint: self.eval_fn( code, stackframe, 'single', ) else: try: # Do some some custom single mode magic that lets us # call the repr function on the last expr. value = progn( code, self.eval_fn, stackframe, ) except QdbPrognEndsInStatement: # Statements have no value to print. pass else: if pprint: value = pformat(value) if repr_fn: value = repr_fn(value) print(value) except Exception as e: outexc = type(e).__name__ outmsg = self.exception_serializer(e) else: outmsg = out.getvalue().rstrip('\n') if outexc is not None or outmsg is not None: self.cmd_manager.send_print(code, outexc, outmsg) self.update_watchlist()