Пример #1
0
def fake_exc_info(exc_info, filename, lineno):
    """Helper for `translate_exception`."""
    exc_type, exc_value, tb = exc_info
    if tb is not None:
        real_locals = tb.tb_frame.f_locals.copy()
        ctx = real_locals.get('context')
        if ctx:
            locals = ctx.get_all()
        else:
            locals = {}
        for name, value in real_locals.iteritems():
            if name.startswith('l_') and value is not missing:
                locals[name[2:]] = value

        locals.pop('__jinja_exception__', None)
    else:
        locals = {}
    globals = {
        '__name__': filename,
        '__file__': filename,
        '__jinja_exception__': exc_info[:2],
        '__jinja_template__': None
    }
    code = compile('\n' * (lineno - 1) + raise_helper, filename, 'exec')
    try:
        if tb is None:
            location = 'template'
        else:
            function = tb.tb_frame.f_code.co_name
            if function == 'root':
                location = 'top-level template code'
            elif function.startswith('block_'):
                location = 'block "%s"' % function[6:]
            else:
                location = 'template'
        code = CodeType(0, code.co_nlocals, code.co_stacksize, code.co_flags,
                        code.co_code, code.co_consts, code.co_names,
                        code.co_varnames, filename, location,
                        code.co_firstlineno, code.co_lnotab, (), ())
    except:
        pass

    try:
        exec code in globals, locals
    except:
        exc_info = sys.exc_info()
        new_tb = exc_info[2].tb_next

    return exc_info[:2] + (new_tb, )
Пример #2
0
def fake_exc_info(exc_info, filename, lineno):
    """Helper for `translate_exception`."""
    exc_type, exc_value, tb = exc_info

    # figure the real context out
    if tb is not None:
        real_locals = tb.tb_frame.f_locals.copy()
        ctx = real_locals.get('context')
        if ctx:
            locals = ctx.get_all()
        else:
            locals = {}
        for name, value in real_locals.iteritems():
            if name.startswith('l_') and value is not missing:
                locals[name[2:]] = value

        # if there is a local called __jinja_exception__, we get
        # rid of it to not break the debug functionality.
        locals.pop('__jinja_exception__', None)
    else:
        locals = {}

    # assamble fake globals we need
    globals = {
        '__name__': filename,
        '__file__': filename,
        '__jinja_exception__': exc_info[:2],

        # we don't want to keep the reference to the template around
        # to not cause circular dependencies, but we mark it as Jinja
        # frame for the ProcessedTraceback
        '__jinja_template__': None
    }

    # and fake the exception
    code = compile('\n' * (lineno - 1) + raise_helper, filename, 'exec')

    # if it's possible, change the name of the code.  This won't work
    # on some python environments such as google appengine
    try:
        if tb is None:
            location = 'template'
        else:
            function = tb.tb_frame.f_code.co_name
            if function == 'root':
                location = 'top-level template code'
            elif function.startswith('block_'):
                location = 'block "%s"' % function[6:]
            else:
                location = 'template'
        code = CodeType(0, code.co_nlocals, code.co_stacksize, code.co_flags,
                        code.co_code, code.co_consts, code.co_names,
                        code.co_varnames, filename, location,
                        code.co_firstlineno, code.co_lnotab, (), ())
    except:
        pass

    # execute the code and catch the new traceback
    try:
        exec code in globals, locals
    except:
        exc_info = sys.exc_info()
        new_tb = exc_info[2].tb_next

    # return without this frame
    return exc_info[:2] + (new_tb, )
Пример #3
0
def fake_exc_info(exc_info, filename, lineno, tb_back=None):
    """Helper for `translate_exception`."""
    exc_type, exc_value, tb = exc_info

    # figure the real context out
    real_locals = tb.tb_frame.f_locals.copy()
    ctx = real_locals.get('context')
    if ctx:
        locals = ctx.get_all()
    else:
        locals = {}
    for name, value in real_locals.iteritems():
        if name.startswith('l_'):
            locals[name[2:]] = value

    # if there is a local called __jinja_exception__, we get
    # rid of it to not break the debug functionality.
    locals.pop('__jinja_exception__', None)

    # assamble fake globals we need
    globals = {
        '__name__': filename,
        '__file__': filename,
        '__jinja_exception__': exc_info[:2]
    }

    # and fake the exception
    code = compile(
        '\n' * (lineno - 1) + 'raise __jinja_exception__[0], ' +
        '__jinja_exception__[1]', filename, 'exec')

    # if it's possible, change the name of the code.  This won't work
    # on some python environments such as google appengine
    try:
        function = tb.tb_frame.f_code.co_name
        if function == 'root':
            location = 'top-level template code'
        elif function.startswith('block_'):
            location = 'block "%s"' % function[6:]
        else:
            location = 'template'
        code = CodeType(0, code.co_nlocals, code.co_stacksize, code.co_flags,
                        code.co_code, code.co_consts, code.co_names,
                        code.co_varnames, filename, location,
                        code.co_firstlineno, code.co_lnotab, (), ())
    except:
        pass

    # execute the code and catch the new traceback
    try:
        exec code in globals, locals
    except:
        exc_info = sys.exc_info()
        new_tb = exc_info[2].tb_next

    # now we can patch the exc info accordingly
    if tb_set_next is not None:
        if tb_back is not None:
            tb_set_next(tb_back, new_tb)
        if tb is not None:
            tb_set_next(new_tb, tb.tb_next)

    # return without this frame
    return exc_info[:2] + (new_tb, )