From d89f0f3defdebbf01a2f9f4a381b7e99a49ced03 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 4 Feb 2009 18:57:27 +0100 Subject: [PATCH] Priority of `not` raised. It's now possible to write `not foo in bar` as an alias to `foo not in bar` like in python. Previously the grammar required parentheses (`not (foo in bar)`) which was odd. --HG-- branch : trunk --- .hgignore | 1 + CHANGES | 3 +++ docs/_static/style.css | 1 + docs/cache_extension.py | 4 ++-- jinja2/parser.py | 14 ++++++++------ tests/test_syntax.py | 6 ++++++ 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.hgignore b/.hgignore index 0aa46ee..eebc869 100644 --- a/.hgignore +++ b/.hgignore @@ -5,3 +5,4 @@ ^(build|dist|Jinja2\.egg-info)/ \.py[co]$ \.DS_Store$ +^env/ diff --git a/CHANGES b/CHANGES index ab75555..9911301 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,9 @@ Version 2.2 - Include statements can now be marked with ``ignore missing`` to skip non existing templates. +- Priority of `not` raised. It's now possible to write `not foo in bar` + as an alias to `foo not in bar` like in python. Previously the grammar + required parentheses (`not (foo in bar)`) which was odd. Version 2.1.1 ------------- diff --git a/docs/_static/style.css b/docs/_static/style.css index e6238d5..a1c4d59 100644 --- a/docs/_static/style.css +++ b/docs/_static/style.css @@ -253,6 +253,7 @@ h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, +dt:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } diff --git a/docs/cache_extension.py b/docs/cache_extension.py index ec0067b..c736a65 100644 --- a/docs/cache_extension.py +++ b/docs/cache_extension.py @@ -51,6 +51,6 @@ class FragmentCacheExtension(Extension): rv = self.environment.fragment_cache.get(key) if rv is None: return rv - rv = caller() - self.environment.fragment_cache.add(key, rv, timeout) + rv = caller() + self.environment.fragment_cache.add(key, rv, timeout) return rv diff --git a/jinja2/parser.py b/jinja2/parser.py index c607540..b6e23df 100644 --- a/jinja2/parser.py +++ b/jinja2/parser.py @@ -333,13 +333,19 @@ class Parser(object): def parse_and(self): lineno = self.stream.current.lineno - left = self.parse_compare() + left = self.parse_not() while self.stream.skip_if('name:and'): - right = self.parse_compare() + right = self.parse_not() left = nodes.And(left, right, lineno=lineno) lineno = self.stream.current.lineno return left + def parse_not(self): + if self.stream.current.test('name:not'): + lineno = self.stream.next().lineno + return nodes.Not(self.parse_not(), lineno=lineno) + return self.parse_compare() + def parse_compare(self): lineno = self.stream.current.lineno expr = self.parse_add() @@ -445,10 +451,6 @@ class Parser(object): def parse_unary(self): token_type = self.stream.current.type lineno = self.stream.current.lineno - if token_type == 'name' and self.stream.current.value == 'not': - self.stream.next() - node = self.parse_unary() - return nodes.Not(node, lineno=lineno) if token_type == 'sub': self.stream.next() node = self.parse_unary() diff --git a/tests/test_syntax.py b/tests/test_syntax.py index 8d14c66..2a8e46f 100644 --- a/tests/test_syntax.py +++ b/tests/test_syntax.py @@ -189,3 +189,9 @@ def test_test_chaining(env): def test_string_concatenation(env): tmpl = env.from_string('{{ "foo" "bar" "baz" }}') assert tmpl.render() == 'foobarbaz' + + +def test_notin(env): + bar = xrange(100) + tmpl = env.from_string('''{{ not 42 in bar }}''') + assert tmpl.render(bar=bar) == unicode(not 42 in bar) -- 2.26.2