Return to Snippet

Revision: 21685
at December 18, 2009 10:52 by freephys


Updated Code
import sys, traceback
def print_exc_plus( ):
    """ Print the usual traceback information, followed by a listing of
        all the local variables in each frame.
    """
    tb = sys.exc_info( )[2]
    while tb.tb_next:
        tb = tb.tb_next
    stack = [  ]
    f = tb.tb_frame
    while f:
        stack.append(f)
        f = f.f_back
    stack.reverse( )
    traceback.print_exc( )
    print "Locals by frame, innermost last"
    for frame in stack:
        print
        print "Frame %s in %s at line %s" % (frame.f_code.co_name,
                                             frame.f_code.co_filename,
                                             frame.f_lineno)
        for key, value in frame.f_locals.items( ):
            print "\t%20s = " % key,
            # we must _absolutely_ avoid propagating exceptions, and str(value)
            # COULD cause any exception, so we MUST catch any...:
            try:
                print value
            except:
                print "<ERROR WHILE PRINTING VALUE>"

data = ["1", "2", 3, "4"]     # Typo: we 'forget' the quotes on data[2]
def pad4(seq):
    """
    Pad each string in seq with zeros up to four places. Note that there
    is no reason to actually write this function; Python already
    does this sort of thing much better.  It's just an example!
    """
    return_value = [  ]
    for thing in seq:
        return_value.append("0" * (4 - len(thing)) + thing)
    return return_value


Here's the (limited) information we get from a normal traceback.print_exc:

>>> try:
...     pad4(data)
... except:
...     traceback.print_exc( )
...
Traceback (most recent call last):
  File "<stdin>", line 2, in ?
  File "<stdin>", line 9, in pad4
TypeError: len( ) of unsized object

>>> try:
...     pad4(data)
... except:
...     print_exc_plus( )
...
Traceback (most recent call last):
  File "<stdin>", line 2, in ?
  File "<stdin>", line 9, in pad4
TypeError: len( ) of unsized object
Locals by frame, innermost last
Frame ? in <stdin> at line 4
                         sys =  <module>
                        pad4 =  <function>
                _ _builtins_ _ =  <module>
                    _ _name_ _ =  _ _main_ _
                        data =  ['1', '2', 3, '4']
                     _ _doc_ _ =  None
              print_exc_plus =  <function>
Frame pad4 in <stdin> at line 9
                       thing =  3
                return_value =  ['0001', '0002']
                         seq =  ['1', '2', 3, '4']

Revision: 21684
at December 18, 2009 10:51 by freephys


Initial Code
import sys, traceback
def print_exc_plus( ):
    """ Print the usual traceback information, followed by a listing of
        all the local variables in each frame.
    """
    tb = sys.exc_info( )[2]
    while tb.tb_next:
        tb = tb.tb_next
    stack = [  ]
    f = tb.tb_frame
    while f:
        stack.append(f)
        f = f.f_back
    stack.reverse( )
    traceback.print_exc( )
    print "Locals by frame, innermost last"
    for frame in stack:
        print
        print "Frame %s in %s at line %s" % (frame.f_code.co_name,
                                             frame.f_code.co_filename,
                                             frame.f_lineno)
        for key, value in frame.f_locals.items( ):
            print "\t%20s = " % key,
            # we must _absolutely_ avoid propagating exceptions, and str(value)
            # COULD cause any exception, so we MUST catch any...:
            try:
                print value
            except:
                print "<ERROR WHILE PRINTING VALUE>"

Initial URL


Initial Description


Initial Title
print_exc_plus : 8.6. Getting More Information from Tracebacks

Initial Tags


Initial Language
Python