items have a higher priority than attributes now. That's compatible with Jinja1...
authorArmin Ronacher <armin.ronacher@active-4.com>
Mon, 26 May 2008 10:21:45 +0000 (12:21 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Mon, 26 May 2008 10:21:45 +0000 (12:21 +0200)
--HG--
branch : trunk

jinja2/environment.py
jinja2/sandbox.py
tests/test_various.py

index dc8bc254c4323232259fbdb2ca314a8d52ffe7f4..acb5c0272d6b211b6d97198a219c33e787a36989 100644 (file)
@@ -288,19 +288,19 @@ class Environment(object):
 
     def subscribe(self, obj, argument):
         """Get an item or attribute of an object."""
-        if isinstance(argument, basestring):
-            try:
-                attr = str(argument)
-            except:
-                pass
-            else:
-                try:
-                    return getattr(obj, attr)
-                except AttributeError:
-                    pass
         try:
             return obj[argument]
         except (TypeError, LookupError):
+            if isinstance(argument, basestring):
+                try:
+                    attr = str(argument)
+                except:
+                    pass
+                else:
+                    try:
+                        return getattr(obj, attr)
+                    except AttributeError:
+                        pass
             return self.undefined(obj=obj, name=argument)
 
     def parse(self, source, name=None, filename=None):
index b0de8e74f0de818829b702d7c040dfb22aa0f37c..ce3369b31d7d5da1a7c6fe7abc63152020c84653 100644 (file)
@@ -164,30 +164,27 @@ class SandboxedEnvironment(Environment):
 
     def subscribe(self, obj, argument):
         """Subscribe an object from sandboxed code."""
-        is_unsafe = False
-        if isinstance(argument, basestring):
-            try:
-                attr = str(argument)
-            except:
-                pass
-            else:
-                try:
-                    value = getattr(obj, attr)
-                except AttributeError:
-                    pass
-                else:
-                    if self.is_safe_attribute(obj, argument, value):
-                        return value
-                    is_unsafe = True
         try:
             return obj[argument]
         except (TypeError, LookupError):
-            if is_unsafe:
-                return self.undefined('access to attribute %r of %r object is'
-                                      ' unsafe.' % (
-                    argument,
-                    obj.__class__.__name__
-                ), name=argument, exc=SecurityError)
+            if isinstance(argument, basestring):
+                try:
+                    attr = str(argument)
+                except:
+                    pass
+                else:
+                    try:
+                        value = getattr(obj, attr)
+                    except AttributeError:
+                        pass
+                    else:
+                        if self.is_safe_attribute(obj, argument, value):
+                            return value
+                        return self.undefined('access to attribute %r of %r '
+                                              'object is unsafe.' % (
+                            argument,
+                            obj.__class__.__name__
+                        ), name=argument, exc=SecurityError)
         return self.undefined(obj=obj, name=argument)
 
     def call(__self, __context, __obj, *args, **kwargs):
index 147f459d573eb37e51489712e410cc5617f21760..7a3882e6358ead9a7b23850936dc75ea9abccc58 100644 (file)
@@ -58,3 +58,13 @@ def test_markup_leaks():
             escape(u"<foo>")
         counts.add(len(gc.get_objects()))
     assert len(counts) == 1, 'ouch, c extension seems to leak objects'
+
+
+def test_item_before_attribute():
+    from jinja2 import Environment
+    from jinja2.sandbox import SandboxedEnvironment
+
+    for env in Environment(), SandboxedEnvironment():
+        tmpl = env.from_string('{{ foo.items() }}')
+        assert tmpl.render(foo={'items': lambda: 42}) == '42'
+        assert tmpl.render(foo={}) == '[]'