switched back to explicit set for assignments.  {% foo = 42 %} becomes {% set foo = 42 %} and {% foo.something() }} becomes {{ void(foo.something() }} with this commit.

--HG--
branch : trunk
diff --git a/jinja2/parser.py b/jinja2/parser.py
index 941e037..f2a129c 100644
--- a/jinja2/parser.py
+++ b/jinja2/parser.py
@@ -13,7 +13,8 @@
 
 
 _statement_keywords = frozenset(['for', 'if', 'block', 'extends', 'print',
-                                 'macro', 'include', 'from', 'import'])
+                                 'macro', 'include', 'from', 'import',
+                                 'set'])
 _compare_operators = frozenset(['eq', 'ne', 'lt', 'lteq', 'gt', 'gteq'])
 
 
@@ -53,36 +54,21 @@
 
     def parse_statement(self):
         """Parse a single statement."""
-        token_type = self.stream.current.type
-        if self.stream.current.type is 'name':
-            if self.stream.current.value in _statement_keywords:
-                return getattr(self, 'parse_' + self.stream.current.value)()
-            elif self.stream.current.value == 'call':
-                return self.parse_call_block()
-            elif self.stream.current.value == 'filter':
-                return self.parse_filter_block()
-            else:
-                ext = self.extensions.get(self.stream.current.value)
-                if ext is not None:
-                    return ext(self)
-        lineno = self.stream.current.lineno
-        expr = self.parse_tuple()
-        if self.stream.current.type == 'assign':
-            result = self.parse_assign(expr)
-        else:
-            result = nodes.ExprStmt(expr, lineno=lineno)
-        return result
-
-    def parse_assign(self, target):
-        """Parse an assign statement."""
-        lineno = self.stream.expect('assign').lineno
-        if not target.can_assign():
-            raise TemplateSyntaxError("can't assign to '%s'" %
-                                      target.__class__.__name__.lower(),
-                                      target.lineno, self.filename)
-        expr = self.parse_tuple()
-        target.set_ctx('store')
-        return nodes.Assign(target, expr, lineno=lineno)
+        token = self.stream.current
+        if token.type is not 'name':
+            raise TemplateSyntaxError('tag name expected', token.lineno,
+                                      self.filename)
+        if token.value in _statement_keywords:
+            return getattr(self, 'parse_' + self.stream.current.value)()
+        if token.value == 'call':
+            return self.parse_call_block()
+        if token.value == 'filter':
+            return self.parse_filter_block()
+        ext = self.extensions.get(token.value)
+        if ext is not None:
+            return ext(self)
+        raise TemplateSyntaxError('unknown tag %r' % token.value,
+                                  token.lineno, self.filename)
 
     def parse_statements(self, end_tokens, drop_needle=False):
         """Parse multiple statements into a list until one of the end tokens
@@ -106,6 +92,14 @@
             self.stream.next()
         return result
 
+    def parse_set(self):
+        """Parse an assign statement."""
+        lineno = self.stream.next().lineno
+        target = self.parse_assign_target()
+        self.stream.expect('assign')
+        expr = self.parse_tuple()
+        return nodes.Assign(target, expr, lineno=lineno)
+
     def parse_for(self):
         """Parse a for loop."""
         lineno = self.stream.expect('name:for').lineno