# stacktrace.py -- Format a traceback with local variables
#
# Nick Barnes, Ravenbrook Limited, 2001-01-19
#
# $Id: //info.ravenbrook.com/project/p4dti/branch/2001-02-21/teamtrack-4507/code/replicator/stacktrace.py#1 $
# 
# Copyright 2000 Ravenbrook Limited.  This document is provided "as is",
# without any express or implied warranty. In no event will the authors
# be held liable for any damages arising from the use of this document.
# You may make and distribute copies and derivative works of this
# document provided that (1) you do not charge a fee for this document or
# for its distribution, and (2) you retain as they appear all copyright
# and licence notices and document history entries, and (3) you append
# descriptions of your modifications to the document history.
#
# -----
# 
# We try to follow the traceback.print_exception() format as closely
# as possible.

import traceback

def format_frame_locals(frame):
    locals = ['    locals:\n']
    for (key, value) in frame.f_locals.items():
        locals.append ("      " + key + ": " + repr(value) + '\n')
    return locals
        
def format_locals(tb):
    locals = []
    while tb != None:
        locals.append(format_frame_locals(tb.tb_frame))
        tb = tb.tb_next
    return locals

def format_exception(exc_type, exc_value, tb):
    try:
        exception = traceback.format_exception_only(exc_type, exc_value)
        locations = traceback.format_tb(tb)
        locals = format_locals(tb)
        formatted = (['Exception:\n'] +
                     exception +
                     ['Traceback (innermost last):\n'])
        while locations != []:
            formatted.append(locations[0])
            formatted = formatted + locals[0]
            del locations[0]
            del locals[0]
        return formatted
    except:
        formatted = (["Couldn't print detailed traceback.\n"] +
                     traceback.format_exception(exc_type, exc_value, tb))
        return formatted

# A. REFERENCES
#
# <none>
#
#
# B. DOCUMENT HISTORY
#
# 2001-01-19  NB  Wrote after a bug report arrived and we realized that
# a traceback without local variables isn't as much use to us as one
# with them.

