Fixing logic mistake when determining auto-invoking. Added tests for this case.

parent 3c5a6db5
......@@ -29,6 +29,7 @@ def _get_value(item, key):
"""
parts = key.split('.')
key = parts[0]
rest = '.'.join(parts[1:])
value = _NOT_FOUND
if isinstance(item, dict):
......@@ -50,16 +51,14 @@ def _get_value(item, key):
attr = getattr(item, key)
# If there are still parts to process (in a dot-notation key),
# we do not automatically invoke the object, even if it's callable.
autocall = len(parts) > 1
autocall = len(rest) == 0
if autocall and _is_callable(attr):
value = attr()
else:
value = attr
for part in parts[1:]:
if value is _NOT_FOUND:
break
value = _get_value(value, part)
if rest and value is not _NOT_FOUND:
value = _get_value(value, rest)
return value
......
......@@ -432,5 +432,17 @@ class ContextTests(unittest.TestCase, AssertIsMixin):
original = Context({"foo": Attachable(bar=Attachable())})
self.assertEquals(original.get(key), None)
def test_dot_notattion__autocall(self):
key = "foo.bar.baz"
# When the last element is callable, it should be automatically invoked
original = Context({"foo": Attachable(bar=Attachable(baz=lambda: "Called!"))})
self.assertEquals(original.get(key), "Called!")
# An element in the middle of the dotted path should NOT be invoked,
# even if it is callable
class Callable(Attachable):
def __call__(self):
return 'Called!'
original = Context({"foo": Callable(bar=Callable(baz='Not called!'))})
self.assertEquals(original.get(key), "Not called!")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment