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.
This commit is contained in:
parent
16f6169c88
commit
08c1fe5569
4
py/vm.c
4
py/vm.c
|
@ -1362,8 +1362,10 @@ unwind_loop:
|
||||||
// Set traceback info (file and line number) where the exception occurred, but not for:
|
// Set traceback info (file and line number) where the exception occurred, but not for:
|
||||||
// - constant GeneratorExit object, because it's const
|
// - constant GeneratorExit object, because it's const
|
||||||
// - exceptions re-raised by END_FINALLY
|
// - exceptions re-raised by END_FINALLY
|
||||||
|
// - exceptions re-raised explicitly by "raise"
|
||||||
if (nlr.ret_val != &mp_const_GeneratorExit_obj
|
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;
|
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_state
|
||||||
ip = mp_decode_uint_skip(ip); // skip n_exc_stack
|
ip = mp_decode_uint_skip(ip); // skip n_exc_stack
|
||||||
|
|
|
@ -57,6 +57,18 @@ except Exception as e:
|
||||||
print('caught')
|
print('caught')
|
||||||
print_exc(e)
|
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
|
# 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.
|
# there is an error right at the end of the bytecode. It should report the correct line.
|
||||||
def f():
|
def f():
|
||||||
|
|
Loading…
Reference in New Issue