From 524bdae950f36d540b18ee5ad7910fadf45e30d1 Mon Sep 17 00:00:00 2001 From: Mike Bayer <mike_mp@zzzcomputing.com> Date: Fri, 5 Mar 2010 01:37:41 +0000 Subject: [PATCH] - RichTraceback(), html_error_template().render(), text_error_template().render() now accept "error" and "traceback" as optional arguments, and these are now actually used. [ticket:122] --- CHANGES | 10 ++++++++++ mako/exceptions.py | 29 ++++++++++++++++++----------- mako/runtime.py | 5 ++++- test/test_exceptions.py | 28 ++++++++++++++++++++++++---- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/CHANGES b/CHANGES index d3ed5ea..badefd8 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,16 @@ is regenerated from parsed Python source. This fixes usage of unicode in <%namespace:defname> tags. [ticket:99] + +- RichTraceback(), html_error_template().render(), + text_error_template().render() now accept "error" + and "traceback" as optional arguments, and + these are now actually used. [ticket:122] + +- The exception output generated when + format_exceptions=True will now be as a Python + unicode if it occurred during render_unicode(), + or an encoded string if during render(). 0.2.6 diff --git a/mako/exceptions.py b/mako/exceptions.py index daba4fd..d59d868 100644 --- a/mako/exceptions.py +++ b/mako/exceptions.py @@ -73,14 +73,18 @@ class RichTraceback(object): """ def __init__(self, error=None, traceback=None): - (self.source, self.lineno) = ("", 0) + self.source, self.lineno = "", 0 if error is None or traceback is None: - t, value, traceback = sys.exc_info() - self.error = value or t - else: - self.error = error + t, value, tback = sys.exc_info() + + if error is None: + error = value or t + + if traceback is None: + traceback = tback + self.error = error self.records = self._init(traceback) if isinstance(self.error, (CompileException, SyntaxException)): @@ -88,11 +92,10 @@ class RichTraceback(object): self.source = self.error.source self.lineno = self.error.lineno self._has_source = True - self.reverse_records = [r for r in self.records] - self.reverse_records.reverse() - self.init_message() + + self._init_message() - def init_message(self): + def _init_message(self): """Find a unicode representation of self.error""" try: self.message = unicode(self.error) @@ -118,13 +121,17 @@ class RichTraceback(object): """return a list of 4-tuple traceback records (i.e. normal python format) with template-corresponding lines remapped to the originating template """ - return self._get_reformatted_records(self.records) + return list(self._get_reformatted_records(self.records)) + @property + def reverse_records(self): + return reversed(self.records) + @property def reverse_traceback(self): """return the same data as traceback, except in reverse order """ - return self._get_reformatted_records(self.reverse_records) + return list(self._get_reformatted_records(self.reverse_records)) def _init(self, trcback): """format a traceback from sys.exc_info() into 7-item tuples, containing diff --git a/mako/runtime.py b/mako/runtime.py index 95828b4..19d79de 100644 --- a/mako/runtime.py +++ b/mako/runtime.py @@ -430,6 +430,9 @@ def _render_error(template, context, error): if context._outputting_as_unicode: context._buffer_stack[:] = [util.FastEncodingBuffer(unicode=True)] else: - context._buffer_stack[:] = [util.FastEncodingBuffer(error_template.output_encoding, error_template.encoding_errors)] + context._buffer_stack[:] = [util.FastEncodingBuffer( + error_template.output_encoding, + error_template.encoding_errors)] + context._with_template = error_template error_template.render_context(context, error=error) diff --git a/test/test_exceptions.py b/test/test_exceptions.py index 57b3bac..e64afc2 100644 --- a/test/test_exceptions.py +++ b/test/test_exceptions.py @@ -86,7 +86,6 @@ ${u'привет'} assert 'RuntimeError: test' in html_error assert "foo = u'日本'" in html_error - def test_py_unicode_error_html_error_template(self): try: raise RuntimeError(u'日本') @@ -106,10 +105,12 @@ ${foobar} ${self.body()} """) - assert '<div class="sourceline">${foobar}</div>' in result_lines(l.get_template("foo.html").render_unicode()) + assert '<div class="sourceline">${foobar}</div>' in \ + result_lines(l.get_template("foo.html").render_unicode()) def test_utf8_format_exceptions(self): - """test that htmlentityreplace formatting is applied to exceptions reported with format_exceptions=True""" + """test that htmlentityreplace formatting is applied to + exceptions reported with format_exceptions=True""" l = TemplateLookup(format_exceptions=True) if util.py3k: @@ -121,6 +122,25 @@ ${foobar} assert u'<div class="sourceline">${\'привет\' + foobar}</div>'\ in result_lines(l.get_template("foo.html").render().decode('utf-8')) else: - assert '<div class="highlight">2 ${u\'привет\' + foobar}</div>' \ + assert '<div class="highlight">2 ${u\'пр'\ + 'ивет\' + foobar}</div>' \ in result_lines(l.get_template("foo.html").render().decode('utf-8')) + + def test_custom_tback(self): + try: + raise RuntimeError("error 1") + foo('bar') + except: + t, v, tback = sys.exc_info() + + try: + raise RuntimeError("error 2") + except: + html_error = exceptions.html_error_template().render(error=t, traceback=tback) + + # obfuscate the text so that this text + # isn't in the 'wrong' exception + assert "".join(reversed(")'rab'(oof")) in html_error + + \ No newline at end of file -- GitLab