Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

handling exceptions in settrace 'return' calls

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?

like image 494
Will Avatar asked Oct 09 '12 07:10

Will


1 Answers

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')
like image 124
ecatmur Avatar answered Oct 17 '22 06:10

ecatmur