Search code examples
pythondecoratortraceback

Traceback Information Lost in Decorator


When running the following code I am unable to get the expected line number from the traceback information I extracted from sys.exc_info() inside a decorator.

import sys


def get_traceback(function):
    def wrapper(*args, **kwargs):
        try:
            function(*args, **kwargs) # line 7
        except:
            return sys.exc_info()[2]
    return wrapper


def inner():
    raise ValueError() # line 14 <--- the expected line number


@get_traceback
def outer():
    inner() # line 19


tb = outer()
print(tb.tb_lineno) # prints 7
print(tb.tb_next.tb_lineno) # prints 19

When a similar call to sys.exc_info() outside of a decorator I am able to get the appropriate line number. What is the cause of this, and what can I do to get the correct line number?

Thanks in advance!


Solution

  • Decorator just adds another step to your traceback.

    Here is how you can get it with traceback built-in library:

    import traceback
    
    tb = outer()
    
    traceback.extract_tb(tb)[-1].lineno
    

    or in previous style, add another tb_next:

    print(tb.tb_next.tb_next.tb_lineno)