summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lord <davidism@gmail.com>2019-12-03 13:25:57 -0800
committerGitHub <noreply@github.com>2019-12-03 13:25:57 -0800
commit28f12c020ea9628f72e13a658a9a6846743fa9c8 (patch)
tree23762a1ce74ed1a58b316a851c6f9ed66f33a3d7
parent09ddf2db4362e461339c5122eb232512723eb126 (diff)
parent2b0d1ed9214c8aaa122b8ee66ab5cef497d48388 (diff)
downloadjinja2-28f12c020ea9628f72e13a658a9a6846743fa9c8.tar.gz
Merge pull request #1112 from pallets/include-syntax-error-source
TemplateSyntaxError from included template has source
-rw-r--r--CHANGES.rst2
-rw-r--r--jinja2/debug.py10
-rw-r--r--tests/test_debug.py23
3 files changed, 25 insertions, 10 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 6df6d24..103dea5 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -90,6 +90,8 @@ Unreleased
``loop``. :issue:`860`
- Constant folding during compilation is applied to some node types
that were previously overlooked. :issue:`733`
+- ``TemplateSyntaxError.source`` is not empty when raised from an
+ included template. :issue:`457`
Version 2.10.3
diff --git a/jinja2/debug.py b/jinja2/debug.py
index 1887fcf..4370b79 100644
--- a/jinja2/debug.py
+++ b/jinja2/debug.py
@@ -21,14 +21,10 @@ def rewrite_traceback_stack(source=None):
:return: A :meth:`sys.exc_info` tuple that can be re-raised.
"""
exc_type, exc_value, tb = sys.exc_info()
- # The new stack of traceback objects, to be joined together by
- # tb_set_next later.
- stack = []
- if isinstance(exc_value, TemplateSyntaxError):
- exc_value.source = source
- # The exception doesn't need to output location info manually.
+ if isinstance(exc_value, TemplateSyntaxError) and not exc_value.translated:
exc_value.translated = True
+ exc_value.source = source
try:
# Remove the old traceback on Python 3, otherwise the frames
@@ -46,6 +42,8 @@ def rewrite_traceback_stack(source=None):
# Skip the frame for the render function.
tb = tb.tb_next
+ stack = []
+
# Build the stack of traceback object, replacing any in template
# code with the source file and line information.
while tb is not None:
diff --git a/tests/test_debug.py b/tests/test_debug.py
index 9e25fbd..eaeb253 100644
--- a/tests/test_debug.py
+++ b/tests/test_debug.py
@@ -14,6 +14,8 @@ import re
import sys
from traceback import format_exception
+from jinja2 import ChoiceLoader
+from jinja2 import DictLoader
from jinja2 import Environment, TemplateSyntaxError
@@ -51,10 +53,9 @@ ZeroDivisionError: (int(eger)? )?division (or modulo )?by zero
''')
def test_syntax_error(self, fs_env):
- # XXX: the .*? is necessary for python3 which does not hide
- # some of the stack frames we don't want to show. Not sure
- # what's up with that, but that is not that critical. Should
- # be fixed though.
+ # The trailing .*? is for PyPy 2 and 3, which don't seem to
+ # clear the exception's original traceback, leaving the syntax
+ # error in the middle of other compiler frames.
self.assert_traceback_matches(lambda: fs_env.get_template('syntaxerror.html'), r'''(?sm)
File ".*?syntaxerror.html", line 4, in (template|<module>)
\{% endif %\}.*?
@@ -70,6 +71,20 @@ ZeroDivisionError: (int(eger)? )?division (or modulo )?by zero
(jinja2\.exceptions\.)?TemplateSyntaxError: wtf
line 42''')
+ def test_include_syntax_error_source(self, filesystem_loader):
+ e = Environment(loader=ChoiceLoader(
+ [
+ filesystem_loader,
+ DictLoader({"inc": "a\n{% include 'syntaxerror.html' %}\nb"}),
+ ]
+ ))
+ t = e.get_template("inc")
+
+ with pytest.raises(TemplateSyntaxError) as exc_info:
+ t.render()
+
+ assert exc_info.value.source is not None
+
def test_local_extraction(self):
from jinja2.debug import get_template_locals
from jinja2.runtime import missing