diff options
-rw-r--r-- | doc/build/unreleased/uri_traceback.rst | 9 | ||||
-rw-r--r-- | mako/exceptions.py | 10 | ||||
-rw-r--r-- | mako/template.py | 9 | ||||
-rw-r--r-- | test/test_exceptions.py | 50 |
4 files changed, 66 insertions, 12 deletions
diff --git a/doc/build/unreleased/uri_traceback.rst b/doc/build/unreleased/uri_traceback.rst new file mode 100644 index 0000000..43787b9 --- /dev/null +++ b/doc/build/unreleased/uri_traceback.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, exceptions + + Fixed issue where the correct file URI would not be shown in the + template-formatted exception traceback if the template filename were not + known. Additionally fixes an issue where stale filenames would be + displayed if a stack trace alternated between different templates. Pull + request courtesy Martin von Gagern. + diff --git a/mako/exceptions.py b/mako/exceptions.py index 283391a..b6388b1 100644 --- a/mako/exceptions.py +++ b/mako/exceptions.py @@ -159,13 +159,17 @@ class RichTraceback(object): if not line: line = "" try: - (line_map, template_lines) = mods[filename] + (line_map, template_lines, template_filename) = mods[filename] except KeyError: try: info = mako.template._get_module_info(filename) module_source = info.code template_source = info.source - template_filename = info.template_filename or filename + template_filename = ( + info.template_filename + or info.template_uri + or filename + ) except KeyError: # A normal .py file (not a Template) if not compat.py3k: @@ -204,7 +208,7 @@ class RichTraceback(object): template_lines = [ line_ for line_ in template_source.split("\n") ] - mods[filename] = (line_map, template_lines) + mods[filename] = (line_map, template_lines, template_filename) template_ln = line_map[lineno - 1] diff --git a/mako/template.py b/mako/template.py index 2cd1ef4..8e87d50 100644 --- a/mako/template.py +++ b/mako/template.py @@ -330,7 +330,7 @@ class Template(object): (code, module) = _compile_text(self, text, filename) self._code = code self._source = text - ModuleInfo(module, None, self, filename, code, text) + ModuleInfo(module, None, self, filename, code, text, uri) elif filename is not None: # if template filename and a module directory, load # a filesystem-based module file, generating if needed @@ -421,7 +421,7 @@ class Template(object): ) module = compat.load_module(self.module_id, path) del sys.modules[self.module_id] - ModuleInfo(module, path, self, filename, None, None) + ModuleInfo(module, path, self, filename, None, None, None) else: # template filename and no module directory, compile code # in memory @@ -429,7 +429,7 @@ class Template(object): code, module = _compile_text(self, data, filename) self._source = None self._code = code - ModuleInfo(module, None, self, filename, code, None) + ModuleInfo(module, None, self, filename, code, None, None) return module @property @@ -584,6 +584,7 @@ class ModuleTemplate(Template): template_filename, module_source, template_source, + module._template_uri, ) self.callable_ = self.module.render_body @@ -641,12 +642,14 @@ class ModuleInfo(object): template_filename, module_source, template_source, + template_uri, ): self.module = module self.module_filename = module_filename self.template_filename = template_filename self.module_source = module_source self.template_source = template_source + self.template_uri = template_uri self._modules[module.__name__] = template._mmarker = self if module_filename: self._modules[module_filename] = self diff --git a/test/test_exceptions.py b/test/test_exceptions.py index 46fbcdd..2ec46cf 100644 --- a/test/test_exceptions.py +++ b/test/test_exceptions.py @@ -398,10 +398,9 @@ raise RuntimeError(msg) # This is the line. t = l.get_template("foo.html") try: t.render() - assert False except: text_error = exceptions.text_error_template().render_unicode() - assert 'File "foo_html", line 4, in render_body' in text_error + assert 'File "foo.html", line 4, in render_body' in text_error assert "raise RuntimeError(msg) # This is the line." in text_error else: assert False @@ -422,12 +421,51 @@ ${foo()} t = l.get_template("foo.html") try: t.render() - assert False except: text_error = exceptions.text_error_template().render_unicode() - sys.stderr.write(text_error) - assert 'File "foo_html", line 7, in render_body' in text_error - assert 'File "foo_html", line 5, in foo' in text_error + assert 'File "foo.html", line 7, in render_body' in text_error + assert 'File "foo.html", line 5, in foo' in text_error assert "raise RuntimeError(msg) # This is the line." in text_error else: assert False + + def test_alternating_file_names(self): + l = TemplateLookup() + l.put_string( + "base.html", + """ +<%! +def broken(): + raise RuntimeError("Something went wrong.") +%> body starts here +<%block name="foo"> + ${broken()} +</%block> + """, + ) + l.put_string( + "foo.html", + """ +<%inherit file="base.html"/> +<%block name="foo"> + ${parent.foo()} +</%block> + """, + ) + t = l.get_template("foo.html") + try: + t.render() + except: + text_error = exceptions.text_error_template().render_unicode() + assert """ + File "base.html", line 5, in render_body + %> body starts here + File "foo.html", line 4, in render_foo + ${parent.foo()} + File "base.html", line 7, in render_foo + ${broken()} + File "base.html", line 4, in broken + raise RuntimeError("Something went wrong.") +""" in text_error + else: + assert False |