From 08c1fe556915c912598d5a5d5db0f5942f3a333d Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 21 Aug 2019 16:08:43 +1000 Subject: [PATCH] py/vm: Don't add traceback info for exceptions that are re-raised. With this patch exceptions that are re-raised have improved tracebacks (less confusing, match CPython), and it makes re-raise slightly more efficient (in time and RAM) because they no longer need to add a traceback. Also general VM performance is not measurably affected. Partially fixes issue #2928. --- py/vm.c | 4 +++- tests/misc/print_exception.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/py/vm.c b/py/vm.c index 64bddd6b5a..84296b463f 100644 --- a/py/vm.c +++ b/py/vm.c @@ -1362,8 +1362,10 @@ unwind_loop: // Set traceback info (file and line number) where the exception occurred, but not for: // - constant GeneratorExit object, because it's const // - exceptions re-raised by END_FINALLY + // - exceptions re-raised explicitly by "raise" if (nlr.ret_val != &mp_const_GeneratorExit_obj - && *code_state->ip != MP_BC_END_FINALLY) { + && *code_state->ip != MP_BC_END_FINALLY + && !(*code_state->ip == MP_BC_RAISE_VARARGS && code_state->ip[1] == 0)) { const byte *ip = code_state->fun_bc->bytecode; ip = mp_decode_uint_skip(ip); // skip n_state ip = mp_decode_uint_skip(ip); // skip n_exc_stack diff --git a/tests/misc/print_exception.py b/tests/misc/print_exception.py index 08b2e4bc48..2067030bf9 100644 --- a/tests/misc/print_exception.py +++ b/tests/misc/print_exception.py @@ -57,6 +57,18 @@ except Exception as e: print('caught') print_exc(e) +# Test that re-raising an exception doesn't add traceback info +try: + try: + f() + except Exception as e: + print('reraise') + print_exc(e) + raise +except Exception as e: + print('caught') + print_exc(e) + # Here we have a function with lots of bytecode generated for a single source-line, and # there is an error right at the end of the bytecode. It should report the correct line. def f():