diff options
-rw-r--r-- | CHANGES.rst | 2 | ||||
-rw-r--r-- | jinja2/debug.py | 10 | ||||
-rw-r--r-- | tests/test_debug.py | 23 |
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 |