]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
TemplateSyntaxError from included template has source 1112/head
authorDavid Lord <davidism@gmail.com>
Tue, 3 Dec 2019 20:54:56 +0000 (12:54 -0800)
committerDavid Lord <davidism@gmail.com>
Tue, 3 Dec 2019 21:22:10 +0000 (13:22 -0800)
CHANGES.rst
jinja2/debug.py
tests/test_debug.py

index 6df6d24282c188041ac230c5d3fdfa82c90e9cde..103dea54f0d63cf37dfb211e28d4a53f92fb7bc3 100644 (file)
@@ -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
index 1887fcf3522f2019366dc93133a519ce79d6481c..4370b797dce05f89112c56d0e98d4dc8fd2a8bf1 100644 (file)
@@ -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:
index 9e25fbd851ecf5d547353de06ef7ad69e43bc590..eaeb25364464756247a733a1d88aadbcd80a443f 100644 (file)
@@ -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