From: Armin Ronacher Date: Sun, 17 Oct 2010 13:53:59 +0000 (+0200) Subject: fixed an operator precedence error introduced in 2.5.2. X-Git-Tag: 2.5.3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=613912d137bc4989f12d1964df97f79ab1e3be88;p=thirdparty%2Fjinja.git 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)". --- diff --git a/CHANGES b/CHANGES index e31a32a8..2d658a2c 100644 --- a/CHANGES +++ b/CHANGES @@ -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 39713a1f..d44229ad 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 9afbca47..008a0a91 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()