def get_frame_info(tb, context_lines=7, simple=False):
    """
    Return a dict of information about a given traceback.
    """
    # line numbers / function / variables
    lineno = tb.tb_lineno
    function = tb.tb_frame.f_code.co_name
    variables = tb.tb_frame.f_locals

    files = {}

    # get filename
    if simple:
        fn = tb.tb_frame.f_code.co_filename
    else:
        fn = tb.tb_frame.f_globals.get('__file__')
        if not fn:
            fn = os.path.realpath(inspect.getsourcefile(tb) or
                                  inspect.getfile(tb))
        if fn[-4:] in ('.pyc', '.pyo'):
            fn = fn[:-1]

    #if filename is existed, then just read the file
    # get loader
    loader = None
    if not os.path.exists(fn):
        loader = tb.tb_frame.f_globals.get('__loader__')
        while not loader and tb.tb_next:
            tb = tb.tb_next
            loader = tb.tb_frame.f_globals.get('__loader__')


    # sourcecode
    source = ''
    pre_context, post_context = [], []
    context_line = raw_context_line = context_lineno = None
    try:
        if loader:
            source = loader.get_source(fn)
        else:
            if not fn in files:
                source = open(fn).read()
                files[fn] = source
            else:
                source = files[fn]
    except:
        pass
    else:
        try:
            raw_context_line = source.splitlines()[lineno - 1].strip()
        except IndexError:
            pass
        if not simple:
            parsed_source = highlight_python(source)
            lbound = max(0, lineno - context_lines - 1)
            ubound = lineno + context_lines
            try:
                context_line = parsed_source[lineno - 1]
                pre_context = parsed_source[lbound:lineno - 1]
                post_context = parsed_source[lineno:ubound]
            except IndexError as e:
                pass
            context_lineno = lbound

    if isinstance(fn, unicode):
        fn = fn.encode('utf-8')
    return {
        'tb':               tb,
        'filename':         fn,
        'basename':         os.path.basename(fn),
        'loader':           loader,
        'function':         function,
        'lineno':           lineno,
        'vars':             variables,
        'pre_context':      pre_context,
        'context_line':     context_line,
        'raw_context_line': raw_context_line,
        'post_context':     post_context,
        'context_lineno':   context_lineno,
        'source':           source
    }
def get_frame_info ( tb , context_lines = 7 , simple = False ) : lineno = tb . tb_lineno function = tb . tb_frame . f_code . co_name variables = tb . tb_frame . f_locals files = { } if simple : fn = tb . tb_frame . f_code . co_filename else : fn = tb . tb_frame . f_globals . get ( '__file__' ) if not fn : fn = os . path . realpath ( inspect . getsourcefile ( tb ) or inspect . getfile ( tb ) ) if fn [ - 4 : ] in ( '.pyc' , '.pyo' ) : fn = fn [ : - 1 ] loader = None if not os . path . exists ( fn ) : loader = tb . tb_frame . f_globals . get ( '__loader__' ) while not loader and tb . tb_next : tb = tb . tb_next loader = tb . tb_frame . f_globals . get ( '__loader__' ) source = '' pre_context , post_context = [ ] , [ ] context_line = raw_context_line = context_lineno = None try : if loader : source = loader . get_source ( fn ) else : if not fn in files : source = open ( fn ) . read ( ) files [ fn ] = source else : source = files [ fn ] except : pass else : try : raw_context_line = source . splitlines ( ) [ lineno - 1 ] . strip ( ) except IndexError : pass if not simple : parsed_source = highlight_python ( source ) lbound = max ( 0 , lineno - context_lines - 1 ) ubound = lineno + context_lines try : context_line = parsed_source [ lineno - 1 ] pre_context = parsed_source [ lbound : lineno - 1 ] post_context = parsed_source [ lineno : ubound ] except IndexError as e : pass context_lineno = lbound if isinstance ( fn , unicode ) : fn = fn . encode ( 'utf-8' ) return { 'tb' : tb , 'filename' : fn , 'basename' : os . path . basename ( fn ) , 'loader' : loader , 'function' : function , 'lineno' : lineno , 'vars' : variables , 'pre_context' : pre_context , 'context_line' : context_line , 'raw_context_line' : raw_context_line , 'post_context' : post_context , 'context_lineno' : context_lineno , 'source' : source }
Return a dict of information about a given traceback.