def translate_exception(template, context, exc_type, exc_value, tb): """ Translate an exception and return the new traceback. """ # depending on the python version we have to skip some frames to # step to get the frame of the current template. The frames before # are the toolchain used to render that thing. for x in xrange(RUNTIME_EXCEPTION_OFFSET): tb = tb.tb_next result_tb = prev_tb = None initial_tb = tb # translate all the jinja frames in this traceback while tb is not None: if tb.tb_frame.f_globals.get('__jinja_template__'): debug_info = tb.tb_frame.f_globals['debug_info'] # the next thing we do is matching the current error line against the # debugging table to get the correct source line. If we can't find the # filename and line number we return the traceback object unaltered. error_line = tb.tb_lineno for code_line, tmpl_filename, tmpl_line in reversed(debug_info): if code_line <= error_line: source = tb.tb_frame.f_globals['template_source'] tb = fake_template_exception(exc_type, exc_value, tb, tmpl_filename, tmpl_line, source, context, prev_tb)[-1] break if result_tb is None: result_tb = tb prev_tb = tb tb = tb.tb_next # under some conditions we cannot translate any frame. in that # situation just return the original traceback. return (exc_type, exc_value, result_tb or intial_tb)
def wrapped(env, context, seq): try: return iter(reversed(seq)).next() except StopIteration: return env.undefined_singleton