fixed bug with static unicode strings and auto escaping

--HG--
branch : trunk
diff --git a/jinja2/compiler.py b/jinja2/compiler.py
index 24cae81..e43c362 100644
--- a/jinja2/compiler.py
+++ b/jinja2/compiler.py
@@ -15,7 +15,7 @@
 from jinja2 import nodes
 from jinja2.visitor import NodeVisitor, NodeTransformer
 from jinja2.exceptions import TemplateAssertionError
-from jinja2.utils import Markup, concat
+from jinja2.utils import Markup, concat, escape
 
 
 operators = {
@@ -1062,8 +1062,20 @@
         body = []
         for child in node.nodes:
             try:
-                const = unicode(child.as_const())
+                const = child.as_const()
+            except nodes.Impossible:
+                body.append(child)
+                continue
+            try:
+                if self.environment.autoescape:
+                    if hasattr(const, '__html__'):
+                        const = const.__html__()
+                    else:
+                        const = escape(const)
+                const = unicode(const)
             except:
+                # if something goes wrong here we evaluate the node
+                # at runtime for easier debugging
                 body.append(child)
                 continue
             if body and isinstance(body[-1], list):
diff --git a/jinja2/environment.py b/jinja2/environment.py
index 95dda11..45d684d 100644
--- a/jinja2/environment.py
+++ b/jinja2/environment.py
@@ -642,8 +642,7 @@
 
     def __init__(self, gen):
         self._gen = gen
-        self._next = gen.next
-        self.buffered = False
+        self.disable_buffering()
 
     def disable_buffering(self):
         """Disable the output buffering."""
diff --git a/jinja2/filters.py b/jinja2/filters.py
index 2cbb46c..ed3d57c 100644
--- a/jinja2/filters.py
+++ b/jinja2/filters.py
@@ -578,8 +578,7 @@
 
 class _GroupTuple(tuple):
     __slots__ = ()
-    grouper = property(itemgetter(0))
-    list = property(itemgetter(1))
+    grouper, list = (property(itemgetter(x)) for x in xrange(2))
 
     def __new__(cls, (key, value)):
         return tuple.__new__(cls, (key, list(value)))
diff --git a/jinja2/lexer.py b/jinja2/lexer.py
index 350023d..64621fd 100644
--- a/jinja2/lexer.py
+++ b/jinja2/lexer.py
@@ -195,7 +195,7 @@
             return self.next()
 
     def skip_if(self, expr):
-        """Like `next_if` but only returns `True` or `False`."""
+        """Like :meth:`next_if` but only returns `True` or `False`."""
         return self.next_if(expr) is not None
 
     def next(self):
diff --git a/jinja2/nodes.py b/jinja2/nodes.py
index 9d32737..568220f 100644
--- a/jinja2/nodes.py
+++ b/jinja2/nodes.py
@@ -251,21 +251,6 @@
     """
     fields = ('nodes',)
 
-    def optimized_nodes(self):
-        """Try to optimize the nodes."""
-        buffer = []
-        for node in self.nodes:
-            try:
-                const = unicode(node.as_const())
-            except:
-                buffer.append(node)
-            else:
-                if buffer and isinstance(buffer[-1], unicode):
-                    buffer[-1] += const
-                else:
-                    buffer.append(const)
-        return buffer
-
 
 class Extends(Stmt):
     """Represents an extends statement."""
diff --git a/tests/test_ext.py b/tests/test_ext.py
index f91b0f7..7da2515 100644
--- a/tests/test_ext.py
+++ b/tests/test_ext.py
@@ -66,3 +66,7 @@
     env = Environment(extensions=[TestExtension])
     tmpl = env.from_string('{% test %}')
     assert tmpl.render() == 'False|42|23|{}'
+
+
+def test_identifier():
+    assert TestExtension.identifier == __name__ + '.TestExtension'
diff --git a/tests/test_filters.py b/tests/test_filters.py
index 559b0b1..6192d54 100644
--- a/tests/test_filters.py
+++ b/tests/test_filters.py
@@ -308,3 +308,11 @@
 def test_forceescape(env):
     tmpl = env.from_string('{{ x|forceescape }}')
     assert tmpl.render(x=Markup('<div />')) == u'&lt;div /&gt;'
+
+
+def test_safe():
+    env = Environment(autoescape=True)
+    tmpl = env.from_string('{{ "<div>foo</div>"|safe }}')
+    assert tmpl.render() == '<div>foo</div>'
+    tmpl = env.from_string('{{ "<div>foo</div>" }}')
+    assert tmpl.render() == '&lt;div&gt;foo&lt;/div&gt;'
diff --git a/tests/test_security.py b/tests/test_security.py
index 0cacf5f..0da2df2 100644
--- a/tests/test_security.py
+++ b/tests/test_security.py
@@ -113,3 +113,8 @@
     assert Markup(Foo()) == '<em>awesome</em>'
     assert Markup('<strong>%s</strong>') % Foo() == \
            '<strong><em>awesome</em></strong>'
+
+    # escaping and unescaping
+    assert escape('"<>&\'') == '&#34;&lt;&gt;&amp;&#39;'
+    assert Markup("<em>Foo &amp; Bar</em>").striptags() == "Foo & Bar"
+    assert Markup("&lt;test&gt;").unescape() == "<test>"