Search code examples
pythonexceptiontraceback

How to get a complete exception stack trace in Python


The following snippet:

import traceback

def a():
    b()

def b():
    try:
        c()
    except:
        traceback.print_exc()

def c():
    assert False

a()

Produces this output:

Traceback (most recent call last):
  File "test.py", line 8, in b
    c()
  File "test.py", line 13, in c
    assert False
AssertionError

What should I use if I want the complete stack trace including the call to a?

If it matters I have Python 2.6.6

edit: What I'd like to get is the same information I'd get if I left the try except out and let the exception propagate to the top level. This snippet for example:

def a():
    b()

def b():
    c()

def c():
    assert False

a()

Produces this output:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    a()
  File "test.py", line 2, in a
    b()
  File "test.py", line 5, in b
    c()
  File "test.py", line 8, in c
    assert False
AssertionError

Solution

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

    import traceback
    import sys
    
    def 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_str
    
    def 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 frame
    Traceback (most recent call last):
      File "exc.py", line 22, in main2
        main3()
      File "exc.py", line 31, in main3
        raise Exception()
    Exception
    
    
    Printing 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