Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions chevron/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ def _html_escape(string):
return string


def _is_instance_of_namedtuple(obj):
"""Tests if an object is a namedtuple"""
return (
isinstance(obj, tuple) and
hasattr(obj, '_asdict') and
hasattr(obj, '_fields')
)


def _get_key(key, scopes, warn, keep, def_ldel, def_rdel):
"""Get a key from the current scope"""

Expand All @@ -61,16 +70,16 @@ def _get_key(key, scopes, warn, keep, def_ldel, def_rdel):
try:
# For every dot seperated key
for child in key.split('.'):
# Move into the scope
try:
# Try subscripting (Normal dictionaries)

# use different methods of access depending on the data structure
# passed:
if isinstance(scope, dict):
scope = scope[child]
except (TypeError, AttributeError):
try:
scope = getattr(scope, child)
except (TypeError, AttributeError):
# Try as a list
scope = scope[int(child)]
elif hasattr(scope, "__dict__") or _is_instance_of_namedtuple(scope):
scope = getattr(scope, child)
else:
# Otherwise, try accessing as a list/tuple
scope = scope[int(child)]

# Return an empty string if falsy, with two exceptions
# 0 should return 0, and False should return False
Expand Down
26 changes: 26 additions & 0 deletions test_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,32 @@ def test_namedtuple_data(self):

self.assertEqual(result, expected)

# Regression test for
# https://github.com/noahmorrison/chevron/issues/104
def test_string_method_names_in_sections_1(self):
args = {
'template': '{{#upper}}{{{.}}} == {{{upper}}}{{/upper}}',
'data': {'upper': 'foo'},
}

result = chevron.render(**args)
expected = 'foo == foo'
self.assertEqual(result, expected)

# Another regression test for
# https://github.com/noahmorrison/chevron/issues/104
def test_string_method_names_in_sections_2(self):
args = {
'template': (
'{{#a}}{{#b}}{{{b}}} '
'{{#upper}}{{{upper}}}{{/upper}}{{/b}}{{/a}}'
),
'data': {'a': [{'upper': 'foo', 'b': 'x'}]},
}
result = chevron.render(**args)
expected = 'x foo'
self.assertEqual(result, expected)

def test_get_key_not_in_dunder_dict_returns_attribute(self):
class C:
foo = "bar"
Expand Down