Skip to content

Commit

Permalink
fixed an operator precedence error introduced in 2.5.2.
Browse files Browse the repository at this point in the history
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)".
  • Loading branch information
mitsuhiko committed Oct 17, 2010
1 parent 9dc0619 commit 613912d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 4 deletions.
9 changes: 9 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
22 changes: 18 additions & 4 deletions jinja2/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ def parse_pow(self):
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':
Expand All @@ -536,8 +536,9 @@ def parse_unary(self, with_postfix=True):
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):
Expand Down Expand Up @@ -661,12 +662,25 @@ def parse_postfix(self, node):
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
Expand Down
6 changes: 6 additions & 0 deletions jinja2/testsuite/lexnparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,12 @@ def test_localset(self):
{{ 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()
Expand Down

0 comments on commit 613912d

Please sign in to comment.