Index: third_party/jinja2/parser.py |
diff --git a/third_party/jinja2/parser.py b/third_party/jinja2/parser.py |
index f60cd018c51fff457dfaea5283b78267a4a0eefd..d24da180ea61aed5aca443cf641658a068a9064c 100644 |
--- a/third_party/jinja2/parser.py |
+++ b/third_party/jinja2/parser.py |
@@ -11,10 +11,9 @@ |
from jinja2 import nodes |
from jinja2.exceptions import TemplateSyntaxError, TemplateAssertionError |
from jinja2.lexer import describe_token, describe_token_expr |
-from jinja2._compat import next, imap |
+from jinja2._compat import imap |
-#: statements that callinto |
_statement_keywords = frozenset(['for', 'if', 'block', 'extends', 'print', |
'macro', 'include', 'from', 'import', |
'set']) |
@@ -169,9 +168,12 @@ class Parser(object): |
"""Parse an assign statement.""" |
lineno = next(self.stream).lineno |
target = self.parse_assign_target() |
- self.stream.expect('assign') |
- expr = self.parse_tuple() |
- return nodes.Assign(target, expr, lineno=lineno) |
+ if self.stream.skip_if('assign'): |
+ expr = self.parse_tuple() |
+ return nodes.Assign(target, expr, lineno=lineno) |
+ body = self.parse_statements(('name:endset',), |
+ drop_needle=True) |
+ return nodes.AssignBlock(target, body, lineno=lineno) |
def parse_for(self): |
"""Parse a for loop.""" |
@@ -312,6 +314,8 @@ class Parser(object): |
arg.set_ctx('param') |
if self.stream.skip_if('assign'): |
defaults.append(self.parse_expression()) |
+ elif defaults: |
+ self.fail('non-default argument follows default argument') |
args.append(arg) |
self.stream.expect('rparen') |
@@ -434,8 +438,8 @@ class Parser(object): |
ops.append(nodes.Operand(token_type, self.parse_add())) |
elif self.stream.skip_if('name:in'): |
ops.append(nodes.Operand('in', self.parse_add())) |
- elif self.stream.current.test('name:not') and \ |
- self.stream.look().test('name:in'): |
+ elif (self.stream.current.test('name:not') and |
+ self.stream.look().test('name:in')): |
self.stream.skip(2) |
ops.append(nodes.Operand('notin', self.parse_add())) |
else: |
@@ -771,7 +775,7 @@ class Parser(object): |
else: |
ensure(dyn_args is None and dyn_kwargs is None) |
if self.stream.current.type == 'name' and \ |
- self.stream.look().type == 'assign': |
+ self.stream.look().type == 'assign': |
key = self.stream.current.value |
self.stream.skip(2) |
value = self.parse_expression() |
@@ -824,11 +828,11 @@ class Parser(object): |
kwargs = [] |
if self.stream.current.type == 'lparen': |
args, kwargs, dyn_args, dyn_kwargs = self.parse_call(None) |
- elif self.stream.current.type in ('name', 'string', 'integer', |
- 'float', 'lparen', 'lbracket', |
- 'lbrace') and not \ |
- self.stream.current.test_any('name:else', 'name:or', |
- 'name:and'): |
+ elif (self.stream.current.type in ('name', 'string', 'integer', |
+ 'float', 'lparen', 'lbracket', |
+ 'lbrace') and not |
+ self.stream.current.test_any('name:else', 'name:or', |
+ 'name:and')): |
if self.stream.current.test('name:is'): |
self.fail('You cannot chain multiple tests with is') |
args = [self.parse_expression()] |