Code

Ticket #16770: unwrap_templatesyntaxerror-2.diff

File unwrap_templatesyntaxerror-2.diff, 17.9 KB (added by jMyles, 3 years ago)

Removed psycopg2 import

Line 
1Index: django/views/debug.py
2===================================================================
3--- django/views/debug.py       (revision 16772)
4+++ django/views/debug.py       (working copy)
5@@ -141,7 +141,7 @@
6                 else:
7                     # Cleanse only the specified parameters.
8                     for param in sensitive_post_parameters:
9-                        if param in cleansed:
10+                        if cleansed.has_key(param):
11                             cleansed[param] = CLEANSED_SUBSTITUTE
12                     return cleansed
13             else:
14@@ -223,8 +223,7 @@
15                     'loader': loader_name,
16                     'templates': template_list,
17                 })
18-        if (settings.TEMPLATE_DEBUG and hasattr(self.exc_value, 'source') and
19-            isinstance(self.exc_value, TemplateSyntaxError)):
20+        if (settings.TEMPLATE_DEBUG and hasattr(self.exc_value, 'django_template_source')):
21             self.get_template_exception_info()
22 
23         frames = self.get_traceback_frames()
24@@ -268,7 +267,7 @@
25         return t.render(c)
26 
27     def get_template_exception_info(self):
28-        origin, (start, end) = self.exc_value.source
29+        origin, (start, end) = self.exc_value.django_template_source
30         template_source = origin.reload()
31         context_lines = 10
32         line = 0
33@@ -626,7 +625,7 @@
34 {% endif %}
35 {% if template_info %}
36 <div id="template">
37-   <h2>Template error</h2>
38+   <h2>Error occured during template rendering</h2>
39    <p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p>
40    <h3>{{ template_info.message }}</h3>
41    <table class="source{% if template_info.top %} cut-top{% endif %}{% ifnotequal template_info.bottom template_info.total %} cut-bottom{% endifnotequal %}">
42Index: django/template/debug.py
43===================================================================
44--- django/template/debug.py    (revision 16772)
45+++ django/template/debug.py    (working copy)
46@@ -4,6 +4,7 @@
47 from django.utils.safestring import SafeData, EscapeData
48 from django.utils.formats import localize
49 
50+
51 class DebugLexer(Lexer):
52     def __init__(self, template_string, origin):
53         super(DebugLexer, self).__init__(template_string, origin)
54@@ -42,9 +43,9 @@
55     def error(self, token, msg):
56         return self.source_error(token.source, msg)
57 
58-    def source_error(self, source,msg):
59+    def source_error(self, source, msg):
60         e = TemplateSyntaxError(msg)
61-        e.source = source
62+        e.source_template_node = source #Identify the template node that was being rendered when the error occurred.
63         return e
64 
65     def create_nodelist(self):
66@@ -67,21 +68,17 @@
67             e.source = token.source
68 
69 class DebugNodeList(NodeList):
70+    '''
71+    A list of nodes that is instantiated when debug is True - this is the nerve center of exceptions that occur during template rendering.
72+    '''
73     def render_node(self, node, context):
74-        try:
75-            result = node.render(context)
76-        except TemplateSyntaxError, e:
77-            if not hasattr(e, 'source'):
78-                e.source = node.source
79-            raise
80+        try:           
81+            return node.render(context)
82         except Exception, e:
83-            from sys import exc_info
84-            wrapped = TemplateSyntaxError(u'Caught %s while rendering: %s' %
85-                (e.__class__.__name__, force_unicode(e, errors='replace')))
86-            wrapped.source = getattr(e, 'template_node_source', node.source)
87-            wrapped.exc_info = exc_info()
88-            raise wrapped, None, wrapped.exc_info[2]
89-        return result
90+            if not hasattr(e, 'source_template_node'): #Have we already identified the node where the problem occured?
91+                e.django_template_source = node.source #...if not, let's annotate the exception with that - the template will use this to show information about the template just before the traceback on the exception page.
92+            raise e
93+       
94 
95 class DebugVariableNode(VariableNode):
96     def render(self, context):
97Index: tests/regressiontests/templates/tests.py
98===================================================================
99--- tests/regressiontests/templates/tests.py    (revision 16772)
100+++ tests/regressiontests/templates/tests.py    (working copy)
101@@ -1,5 +1,6 @@
102 # -*- coding: utf-8 -*-
103 from django.conf import settings
104+from django.core.urlresolvers import NoReverseMatch
105 
106 if __name__ == '__main__':
107     # When running this file in isolation, we need to set up the configuration
108@@ -20,7 +21,7 @@
109 from django.template import loader
110 from django.template.loaders import app_directories, filesystem, cached
111 from django.test.utils import (get_warnings_state, restore_warnings_state,
112-    setup_test_template_loader, restore_template_loaders)
113+    setup_test_template_loader, restore_template_loaders, override_settings)
114 from django.utils import unittest
115 from django.utils.formats import date_format
116 from django.utils.translation import activate, deactivate, ugettext as _
117@@ -309,9 +310,9 @@
118             r = None
119             try:
120                 r = tmpl.render(template.Context({}))
121-            except template.TemplateSyntaxError, e:
122+            except template.TemplateDoesNotExist, e:
123                 settings.TEMPLATE_DEBUG = old_td
124-                self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html')
125+                self.assertEqual(e.args[0], 'missing.html')
126             self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
127         finally:
128             loader.template_source_loaders = old_loaders
129@@ -336,8 +337,8 @@
130             r = None
131             try:
132                 r = tmpl.render(template.Context({}))
133-            except template.TemplateSyntaxError, e:
134-                self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html')
135+            except template.TemplateDoesNotExist, e:
136+                self.assertEqual(e.args[0], 'missing.html')
137             self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
138 
139             # For the cached loader, repeat the test, to ensure the first attempt did not cache a
140@@ -345,8 +346,8 @@
141             tmpl = loader.get_template(load_name)
142             try:
143                 tmpl.render(template.Context({}))
144-            except template.TemplateSyntaxError, e:
145-                self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html')
146+            except template.TemplateDoesNotExist, e:
147+                self.assertEqual(e.args[0], 'missing.html')
148             self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
149         finally:
150             loader.template_source_loaders = old_loaders
151@@ -370,15 +371,26 @@
152 
153         t = Template('{% url will_not_match %}')
154         c = Context()
155-        try:
156-            rendered = t.render(c)
157-        except TemplateSyntaxError, e:
158-            # Assert that we are getting the template syntax error and not the
159-            # string encoding error.
160-            self.assertEqual(e.args[0], "Caught NoReverseMatch while rendering: Reverse for 'will_not_match' with arguments '()' and keyword arguments '{}' not found.")
161+        self.assertRaises(NoReverseMatch, t.render, c)
162 
163         settings.SETTINGS_MODULE = old_settings_module
164         settings.TEMPLATE_DEBUG = old_template_debug
165+       
166+    @override_settings(DEBUG=True, TEMPLATE_DEBUG = True)
167+    def test_no_wrapped_exception(self):
168+        """
169+        Previously exceptions were wrapped by TemplateSyntaxError.  See #16770
170+        """
171+        from django.template import Template, TemplateSyntaxError
172+        c = Context({'coconuts': lambda: 42 / 0})
173+        t = Template("{{coconuts}}")       
174+        self.assertRaises(ZeroDivisionError, t.render, c) #Dividing by zero ought to cause ZeroDivisionError; we'll instead get TemplateSyntaxError here iff it's been wrapped.
175+       
176+        #Let's also confirm that the exception has the attribute we need to show the template information on the exception page.
177+        try:
178+            t.render(c)
179+        except ZeroDivisionError, e:
180+            self.assertTrue(hasattr(e, 'django_template_source'))
181 
182     def test_invalid_block_suggestion(self):
183         # See #7876
184@@ -666,7 +678,7 @@
185 
186             # In methods that raise an exception without a
187             # "silent_variable_attribute" set to True, the exception propagates
188-            'filter-syntax14': (r'1{{ var.method4 }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException, template.TemplateSyntaxError)),
189+            'filter-syntax14': (r'1{{ var.method4 }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException)),
190 
191             # Escaped backslash in argument
192             'filter-syntax15': (r'{{ var|default_if_none:"foo\bar" }}', {"var": None}, r'foo\bar'),
193@@ -695,8 +707,8 @@
194             # In attribute and dict lookups that raise an unexpected exception
195             # without a "silent_variable_attribute" set to True, the exception
196             # propagates
197-            'filter-syntax23': (r'1{{ var.noisy_fail_key }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException, template.TemplateSyntaxError)),
198-            'filter-syntax24': (r'1{{ var.noisy_fail_attribute }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException, template.TemplateSyntaxError)),
199+            'filter-syntax23': (r'1{{ var.noisy_fail_key }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException)),
200+            'filter-syntax24': (r'1{{ var.noisy_fail_attribute }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException)),
201 
202             ### COMMENT SYNTAX ########################################################
203             'comment-syntax01': ("{# this is hidden #}hello", {}, "hello"),
204@@ -753,7 +765,7 @@
205             ### EXCEPTIONS ############################################################
206 
207             # Raise exception for invalid template name
208-            'exception01': ("{% extends 'nonexistent' %}", {}, (template.TemplateDoesNotExist, template.TemplateDoesNotExist, template.TemplateSyntaxError)),
209+            'exception01': ("{% extends 'nonexistent' %}", {}, (template.TemplateDoesNotExist, template.TemplateDoesNotExist)),
210 
211             # Raise exception for invalid template name (in variable)
212             'exception02': ("{% extends nonexistent %}", {}, (template.TemplateSyntaxError, template.TemplateDoesNotExist)),
213@@ -1050,7 +1062,7 @@
214             'include-fail2': ('{% load broken_tag %}', {}, template.TemplateSyntaxError),
215             'include-error07': ('{% include "include-fail1" %}', {}, ('', '', RuntimeError)),
216             'include-error08': ('{% include "include-fail2" %}', {}, ('', '', template.TemplateSyntaxError)),
217-            'include-error09': ('{% include failed_include %}', {'failed_include': 'include-fail1'}, ('', '', template.TemplateSyntaxError)),
218+            'include-error09': ('{% include failed_include %}', {'failed_include': 'include-fail1'}, ('', '', RuntimeError)),
219             'include-error10': ('{% include failed_include %}', {'failed_include': 'include-fail2'}, ('', '', template.TemplateSyntaxError)),
220 
221 
222@@ -1481,8 +1493,8 @@
223 
224             # Failures
225             'old-url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
226-            'old-url-fail02': ('{% url no_such_view %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
227-            'old-url-fail03': ('{% url regressiontests.templates.views.client %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
228+            'old-url-fail02': ('{% url no_such_view %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
229+            'old-url-fail03': ('{% url regressiontests.templates.views.client %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
230             'old-url-fail04': ('{% url view id, %}', {}, template.TemplateSyntaxError),
231             'old-url-fail05': ('{% url view id= %}', {}, template.TemplateSyntaxError),
232             'old-url-fail06': ('{% url view a.id=id %}', {}, template.TemplateSyntaxError),
233@@ -1522,8 +1534,8 @@
234 
235             # Failures
236             'url-fail01': ('{% load url from future %}{% url %}', {}, template.TemplateSyntaxError),
237-            'url-fail02': ('{% load url from future %}{% url "no_such_view" %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
238-            'url-fail03': ('{% load url from future %}{% url "regressiontests.templates.views.client" %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
239+            'url-fail02': ('{% load url from future %}{% url "no_such_view" %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
240+            'url-fail03': ('{% load url from future %}{% url "regressiontests.templates.views.client" %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
241             'url-fail04': ('{% load url from future %}{% url "view" id, %}', {}, template.TemplateSyntaxError),
242             'url-fail05': ('{% load url from future %}{% url "view" id= %}', {}, template.TemplateSyntaxError),
243             'url-fail06': ('{% load url from future %}{% url "view" a.id=id %}', {}, template.TemplateSyntaxError),
244@@ -1531,9 +1543,9 @@
245             'url-fail08': ('{% load url from future %}{% url "view" id="unterminatedstring %}', {}, template.TemplateSyntaxError),
246             'url-fail09': ('{% load url from future %}{% url "view" id=", %}', {}, template.TemplateSyntaxError),
247 
248-            'url-fail11': ('{% load url from future %}{% url named_url %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
249-            'url-fail12': ('{% load url from future %}{% url named_url %}', {'named_url': 'no_such_view'}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
250-            'url-fail13': ('{% load url from future %}{% url named_url %}', {'named_url': 'regressiontests.templates.views.client'}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
251+            'url-fail11': ('{% load url from future %}{% url named_url %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
252+            'url-fail12': ('{% load url from future %}{% url named_url %}', {'named_url': 'no_such_view'}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
253+            'url-fail13': ('{% load url from future %}{% url named_url %}', {'named_url': 'regressiontests.templates.views.client'}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
254             'url-fail14': ('{% load url from future %}{% url named_url id, %}', {'named_url': 'view'}, template.TemplateSyntaxError),
255             'url-fail15': ('{% load url from future %}{% url named_url id= %}', {'named_url': 'view'}, template.TemplateSyntaxError),
256             'url-fail16': ('{% load url from future %}{% url named_url a.id=id %}', {'named_url': 'view'}, template.TemplateSyntaxError),
257Index: tests/regressiontests/templates/nodelist.py
258===================================================================
259--- tests/regressiontests/templates/nodelist.py (revision 16772)
260+++ tests/regressiontests/templates/nodelist.py (working copy)
261@@ -2,6 +2,7 @@
262 from django.template import VariableNode, Context, TemplateSyntaxError
263 from django.template.loader import get_template_from_string
264 from django.utils.unittest import TestCase
265+from django.test.utils import override_settings
266 
267 class NodelistTest(TestCase):
268 
269@@ -35,19 +36,16 @@
270     Checks whether index of error is calculated correctly in
271     template debugger in for loops. Refs ticket #5831
272     """
273-    def setUp(self):
274-        self.old_template_debug = settings.TEMPLATE_DEBUG
275-        settings.TEMPLATE_DEBUG = True
276-
277-    def tearDown(self):
278-        settings.TEMPLATE_DEBUG = self.old_template_debug
279-
280+    @override_settings(DEBUG=True, TEMPLATE_DEBUG = True)
281     def test_correct_exception_index(self):
282-        tests = [
283-            ('{% load bad_tag %}{% for i in range %}{% badsimpletag %}{% endfor %}', (38, 56)),
284-            ('{% load bad_tag %}{% for i in range %}{% for j in range %}{% badsimpletag %}{% endfor %}{% endfor %}', (58, 76)),
285-            ('{% load bad_tag %}{% for i in range %}{% badsimpletag %}{% for j in range %}Hello{% endfor %}{% endfor %}', (38, 56)),
286-            ('{% load bad_tag %}{% for i in range %}{% for j in five %}{% badsimpletag %}{% endfor %}{% endfor %}', (38, 57)),
287+        '''
288+        Looks at an exception page and confirms that the information about the source of an error that occurs during template rendering appears in the appropriate location.
289+        '''
290+        tests = [ #In each case, we have template contents and the lines at which we expect the template error information to occur.
291+            ('{% load bad_tag %}{% for i in range %}{% badsimpletag %}{% endfor %}', (18, 38)),
292+            ('{% load bad_tag %}{% for i in range %}{% for j in range %}{% badsimpletag %}{% endfor %}{% endfor %}', (18, 38)),
293+            ('{% load bad_tag %}{% for i in range %}{% badsimpletag %}{% for j in range %}Hello{% endfor %}{% endfor %}', (18, 38)),
294+            ('{% load bad_tag %}{% for i in range %}{% for j in five %}{% badsimpletag %}{% endfor %}{% endfor %}', (18, 38)),
295             ('{% load bad_tag %}{% for j in five %}{% badsimpletag %}{% endfor %}', (18, 37)),
296         ]
297         context = Context({
298@@ -58,7 +56,7 @@
299             template = get_template_from_string(source)
300             try:
301                 template.render(context)
302-            except TemplateSyntaxError, e:
303-                error_source_index = e.source[1]
304+            except (RuntimeError, TypeError), e:
305+                error_source_index = e.django_template_source[1]
306                 self.assertEqual(error_source_index,
307                                  expected_error_source_index)