items have a higher priority than attributes now. That's compatible with Jinja1 and Django
--HG--
branch : trunk
diff --git a/jinja2/environment.py b/jinja2/environment.py
index dc8bc25..acb5c02 100644
--- a/jinja2/environment.py
+++ b/jinja2/environment.py
@@ -288,19 +288,19 @@
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):
diff --git a/jinja2/sandbox.py b/jinja2/sandbox.py
index b0de8e7..ce3369b 100644
--- a/jinja2/sandbox.py
+++ b/jinja2/sandbox.py
@@ -164,30 +164,27 @@
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):
diff --git a/tests/test_various.py b/tests/test_various.py
index 147f459..7a3882e 100644
--- a/tests/test_various.py
+++ b/tests/test_various.py
@@ -58,3 +58,13 @@
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={}) == '[]'