aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin von Gagern <gagern@google.com>2019-07-02 17:10:23 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2019-07-08 11:20:30 -0400
commit65f8a3b715e8519ca5ca5d835240fe45aa4b96fa (patch)
treefbd40dc07c0abea544499636df34d1f9e5bed907
parent4861e0d58fdfe2bd15d4d26beb0b8163ce3a6637 (diff)
downloadexternal_python_mako-65f8a3b715e8519ca5ca5d835240fe45aa4b96fa.tar.gz
external_python_mako-65f8a3b715e8519ca5ca5d835240fe45aa4b96fa.tar.bz2
external_python_mako-65f8a3b715e8519ca5ca5d835240fe45aa4b96fa.zip
Include URI in traceback if filename is unknown
Using URIs as entrered will make the stack trace arguably more readable than using the module name which is the URI with non-word characters replaced by underscores. This change also fixes a mistake where a mods cache hit would not update template_filename, causing a stale filename to be displayed if the stack trace alternates between different templates. There now is a test case for this. Closes: #298 Pull-request: https://github.com/sqlalchemy/mako/pull/298 Pull-request-sha: ea35208d504932561711cdb574ec1f7def1e7060 Change-Id: Ieb606f6b6b7f4602d4d56694dd0bccf6dc287d20
-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