How to get a complete exception stack trace in Python How to get a complete exception stack trace in Python python python

How to get a complete exception stack trace in Python


Here's a function based on this answer. It will also work when no exception is present:

def full_stack():    import traceback, sys    exc = sys.exc_info()[0]    stack = traceback.extract_stack()[:-1]  # last one would be full_stack()    if exc is not None:  # i.e. an exception is present        del stack[-1]       # remove call of full_stack, the printed exception                            # will contain the caught exception caller instead    trc = 'Traceback (most recent call last):\n'    stackstr = trc + ''.join(traceback.format_list(stack))    if exc is not None:         stackstr += '  ' + traceback.format_exc().lstrip(trc)    return stackstr

print full_stack() will print the full stack trace up to the top, including e.g. IPython's interactiveshell.py calls, since there is (to my knowledge) no way of knowing who would catch exceptions. It's probably not worth figuring out anyway...

If print full_stack() is called from within an except block, full_stack will include the stack trace down to the raise. In the standard Python interpreter, this will be identical to the message you receive when not catching the exception (Which is why that del stack[-1] is there, you don't care about the except block but about the try block).


I don't know if there is a better way, but here's what I did:

import tracebackimport sysdef format_exception(e):    exception_list = traceback.format_stack()    exception_list = exception_list[:-2]    exception_list.extend(traceback.format_tb(sys.exc_info()[2]))    exception_list.extend(traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1]))    exception_str = "Traceback (most recent call last):\n"    exception_str += "".join(exception_list)    # Removing the last \n    exception_str = exception_str[:-1]    return exception_strdef main1():    main2()def main2():    try:        main3()    except Exception as e:        print "Printing only the traceback above the current stack frame"        print "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))        print        print "Printing the full traceback as if we had not caught it here..."        print format_exception(e)def main3():    raise Exception()if __name__ == '__main__':    main1()

And here's the output I get:

Printing only the traceback above the current stack frameTraceback (most recent call last):  File "exc.py", line 22, in main2    main3()  File "exc.py", line 31, in main3    raise Exception()ExceptionPrinting the full traceback as if we had not caught it here...Traceback (most recent call last):  File "exc.py", line 34, in <module>    main1()  File "exc.py", line 18, in main1    main2()  File "exc.py", line 22, in main2    main3()  File "exc.py", line 31, in main3    raise Exception()Exception


Use

 traceback.print_stack()

http://docs.python.org/library/traceback.html#traceback.print_stack

suxmac2 $ python out.py   File "out.py", line 16, in <module>    a()  File "out.py", line 5, in a    b()  File "out.py", line 11, in b    traceback.print_stack()