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, )
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, )
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, )