aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/build/unreleased/uri_traceback.rst9
-rw-r--r--mako/exceptions.py10
-rw-r--r--mako/template.py9
-rw-r--r--test/test_exceptions.py50
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