diff options
author | Armin Ronacher <armin.ronacher@active-4.com> | 2010-10-17 15:53:59 +0200 |
---|---|---|
committer | Armin Ronacher <armin.ronacher@active-4.com> | 2010-10-17 15:53:59 +0200 |
commit | 613912d137bc4989f12d1964df97f79ab1e3be88 (patch) | |
tree | e5bd17cc03ed9d1c4407be06d27984e63a08a3bb | |
parent | 9dc0619d6528e9fbef328faf56a982d4af7379ba (diff) | |
download | jinja2-613912d137bc4989f12d1964df97f79ab1e3be88.tar.gz |
fixed an operator precedence error introduced in 2.5.2.2.5.3
Statements like "-foo.bar" had their implicit parentheses applied around
the first part of the expression ("(-foo).bar") instead of the more
correct "-(foo.bar)".
-rw-r--r-- | CHANGES | 9 | ||||
-rw-r--r-- | jinja2/parser.py | 22 | ||||
-rw-r--r-- | jinja2/testsuite/lexnparse.py | 6 |
3 files changed, 33 insertions, 4 deletions
@@ -1,6 +1,15 @@ Jinja2 Changelog ================ +Version 2.5.3 +------------- +(bugfix release, release date to be announced) + +- fixed an operator precedence error introduced in 2.5.2. Statements + like "-foo.bar" had their implicit parentheses applied around the + first part of the expression ("(-foo).bar") instead of the more + correct "-(foo.bar)". + Version 2.5.2 ------------- (bugfix release, released on August 18th 2010) diff --git a/jinja2/parser.py b/jinja2/parser.py index 39713a1..d44229a 100644 --- a/jinja2/parser.py +++ b/jinja2/parser.py @@ -525,7 +525,7 @@ class Parser(object): lineno = self.stream.current.lineno return left - def parse_unary(self, with_postfix=True): + def parse_unary(self, with_filter=True): token_type = self.stream.current.type lineno = self.stream.current.lineno if token_type == 'sub': @@ -536,8 +536,9 @@ class Parser(object): node = nodes.Pos(self.parse_unary(False), lineno=lineno) else: node = self.parse_primary() - if with_postfix: - node = self.parse_postfix(node) + node = self.parse_postfix(node) + if with_filter: + node = self.parse_filter_expr(node) return node def parse_primary(self): @@ -661,12 +662,25 @@ class Parser(object): token_type = self.stream.current.type if token_type == 'dot' or token_type == 'lbracket': node = self.parse_subscript(node) + # calls are valid both after postfix expressions (getattr + # and getitem) as well as filters and tests elif token_type == 'lparen': node = self.parse_call(node) - elif token_type == 'pipe': + else: + break + return node + + def parse_filter_expr(self, node): + while 1: + token_type = self.stream.current.type + if token_type == 'pipe': node = self.parse_filter(node) elif token_type == 'name' and self.stream.current.value == 'is': node = self.parse_test(node) + # calls are valid both after postfix expressions (getattr + # and getitem) as well as filters and tests + elif token_type == 'lparen': + node = self.parse_call(node) else: break return node diff --git a/jinja2/testsuite/lexnparse.py b/jinja2/testsuite/lexnparse.py index 9afbca4..008a0a9 100644 --- a/jinja2/testsuite/lexnparse.py +++ b/jinja2/testsuite/lexnparse.py @@ -375,6 +375,12 @@ class SyntaxTestCase(JinjaTestCase): {{ foo }}''') assert tmpl.render() == '0' + def test_parse_unary(self): + tmpl = env.from_string('{{ -foo["bar"] }}') + assert tmpl.render(foo={'bar': 42}) == '-42' + tmpl = env.from_string('{{ -foo["bar"]|abs }}') + assert tmpl.render(foo={'bar': 42}) == '42' + def suite(): suite = unittest.TestSuite() |