In Python 2.x, the frame object passed into a settrace
handler had an f_exc_type
attribute.
In Python 3.x, this f_exc_type
has been removed.
If a function is propagating an exception, the trace 'return' is called but the argument is None
and sys.exc_info()
is (None,None,None)
. This is described in the docs:
[return]
A function (or other code block) is about to return. The local trace function is called; arg is the value that will be returned, or None if the event is caused by an exception being raised. The trace function’s return value is ignored.
In Python 3, how can a tracer determine in a return
hook that an exception is being propagated? How can it differentiate it from a function returning None
normally?
This does seem fairly broken. It's a bit of a hack, but you can tell the difference by looking at the bytecode for the last instruction:
import opcode
def tracer(frame, event, arg):
if event == 'return':
if arg is not None or (opcode.opname[frame.f_code.co_code[frame.f_lasti]]
in ('RETURN_VALUE', 'YIELD_VALUE')):
print('exit via return', arg)
else:
print('exit via exception')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With