From b53b4d5c107dbd56386c599582f46c522877a651 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 10 Sep 2015 21:05:00 -0600 Subject: [PATCH] Fixed #25404 -- Added line numbers to TemplateSyntaxError strings. This makes it much easier to diagnose a test failure when all you have is the stack trace from an uncaught TemplateSyntaxError. --- django/template/base.py | 22 ++++++++++++++----- .../template_tests/syntax_tests/test_basic.py | 8 +++---- .../syntax_tests/test_filter_syntax.py | 11 +++++++++- tests/template_tests/tests.py | 2 +- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/django/template/base.py b/django/template/base.py index f15f8a6ff6..f4d6b0e6b0 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -470,7 +470,7 @@ class Parser(object): self.extend_nodelist(nodelist, TextNode(token.contents), token) elif token.token_type == 1: # TOKEN_VAR if not token.contents: - raise self.error(token, 'Empty variable tag') + raise self.error(token, 'Empty variable tag on line %d' % token.lineno) try: filter_expression = self.compile_filter(token.contents) except TemplateSyntaxError as e: @@ -481,7 +481,7 @@ class Parser(object): try: command = token.contents.split()[0] except IndexError: - raise self.error(token, 'Empty block tag') + raise self.error(token, 'Empty block tag on line %d' % token.lineno) if command in parse_until: # A matching token has been reached. Return control to # the caller. Put the token back on the token list so the @@ -545,13 +545,23 @@ class Parser(object): def invalid_block_tag(self, token, command, parse_until=None): if parse_until: - raise self.error(token, "Invalid block tag: '%s', expected %s" % - (command, get_text_list(["'%s'" % p for p in parse_until]))) - raise self.error(token, "Invalid block tag: '%s'" % command) + raise self.error( + token, + "Invalid block tag on line %d: '%s', expected %s" % ( + token.lineno, + command, + get_text_list(["'%s'" % p for p in parse_until]), + ), + ) + raise self.error(token, "Invalid block tag on line %d: '%s'" % (token.lineno, command)) def unclosed_block_tag(self, parse_until): command, token = self.command_stack.pop() - msg = "Unclosed tag '%s'. Looking for one of: %s." % (command, ', '.join(parse_until)) + msg = "Unclosed tag on line %d: '%s'. Looking for one of: %s." % ( + token.lineno, + command, + ', '.join(parse_until), + ) raise self.error(token, msg) def next_token(self): diff --git a/tests/template_tests/syntax_tests/test_basic.py b/tests/template_tests/syntax_tests/test_basic.py index da45fe2839..0a1c10cee8 100644 --- a/tests/template_tests/syntax_tests/test_basic.py +++ b/tests/template_tests/syntax_tests/test_basic.py @@ -61,7 +61,7 @@ class BasicSyntaxTests(SimpleTestCase): """ Raise TemplateSyntaxError for empty variable tags. """ - with self.assertRaises(TemplateSyntaxError): + with self.assertRaisesMessage(TemplateSyntaxError, 'Empty variable tag on line 1'): self.engine.get_template('basic-syntax07') @setup({'basic-syntax08': '{{ }}'}) @@ -69,7 +69,7 @@ class BasicSyntaxTests(SimpleTestCase): """ Raise TemplateSyntaxError for empty variable tags. """ - with self.assertRaises(TemplateSyntaxError): + with self.assertRaisesMessage(TemplateSyntaxError, 'Empty variable tag on line 1'): self.engine.get_template('basic-syntax08') @setup({'basic-syntax09': '{{ var.method }}'}) @@ -314,13 +314,13 @@ class BasicSyntaxTests(SimpleTestCase): @setup({'template': '{% block content %}'}) def test_unclosed_block(self): - msg = "Unclosed tag 'block'. Looking for one of: endblock." + msg = "Unclosed tag on line 1: 'block'. Looking for one of: endblock." with self.assertRaisesMessage(TemplateSyntaxError, msg): self.engine.render_to_string('template') @setup({'template': '{% if a %}'}) def test_unclosed_block2(self): - msg = "Unclosed tag 'if'. Looking for one of: elif, else, endif." + msg = "Unclosed tag on line 1: 'if'. Looking for one of: elif, else, endif." with self.assertRaisesMessage(TemplateSyntaxError, msg): self.engine.render_to_string('template') diff --git a/tests/template_tests/syntax_tests/test_filter_syntax.py b/tests/template_tests/syntax_tests/test_filter_syntax.py index 1793fc67de..e9f0491d6e 100644 --- a/tests/template_tests/syntax_tests/test_filter_syntax.py +++ b/tests/template_tests/syntax_tests/test_filter_syntax.py @@ -71,9 +71,18 @@ class FilterSyntaxTests(SimpleTestCase): """ Raise TemplateSyntaxError for empty block tags """ - with self.assertRaises(TemplateSyntaxError): + with self.assertRaisesMessage(TemplateSyntaxError, 'Empty block tag on line 1'): self.engine.get_template('filter-syntax08') + @setup({'filter-syntax08-multi-line': "line 1\nline 2\nline 3{% %}\nline 4\nline 5"}) + def test_filter_syntax08_multi_line(self): + """ + Raise TemplateSyntaxError for empty block tags in templates with + multiple lines. + """ + with self.assertRaisesMessage(TemplateSyntaxError, 'Empty block tag on line 3'): + self.engine.get_template('filter-syntax08-multi-line') + @setup({'filter-syntax09': '{{ var|cut:"o"|upper|lower }}'}) def test_filter_syntax09(self): """ diff --git a/tests/template_tests/tests.py b/tests/template_tests/tests.py index 39f0b427d6..a6aac5b81a 100644 --- a/tests/template_tests/tests.py +++ b/tests/template_tests/tests.py @@ -74,7 +74,7 @@ class TemplateTests(SimpleTestCase): self.assertEqual( e.exception.args[0], - "Invalid block tag: 'endblock', expected 'elif', 'else' or 'endif'", + "Invalid block tag on line 1: 'endblock', expected 'elif', 'else' or 'endif'", ) def test_compile_filter_expression_error(self):