From: Thomas Hebb Date: Sat, 23 May 2020 03:24:22 +0000 (-0400) Subject: Allow field access for namedtuple in Python 3 X-Git-Url: https://git.devinivas.org/?a=commitdiff_plain;h=2a9dcdeb8fefae44de19a94d09bffb44eadd9e13;p=chevron.git Allow field access for namedtuple in Python 3 `namedtuple` in Python 3 does not provide a `__dict__` attribute. See https://bugs.python.org/issue24931 for rationale why. As such, if we want to render keys in `namedtuple`s, we need to use its [`_asdict`][1] method. [1]: https://docs.python.org/3/library/collections.html#collections.somenamedtuple._asdict --- diff --git a/chevron/renderer.py b/chevron/renderer.py index 99415da..dfc2a40 100644 --- a/chevron/renderer.py +++ b/chevron/renderer.py @@ -66,11 +66,16 @@ def _get_key(key, scopes): scope = scope[child] except (TypeError, AttributeError): try: - # Try the dictionary (Complex types) - scope = scope.__dict__[child] + # Try namedtuple (which does not have __dict__ in + # Python 3: https://bugs.python.org/issue24931) + scope = scope._asdict()[child] except (TypeError, AttributeError): - # Try as a list - scope = scope[int(child)] + try: + # Try the dictionary (Complex types) + scope = scope.__dict__[child] + except (TypeError, AttributeError): + # Try as a list + scope = scope[int(child)] # Return an empty string if falsy, with two exceptions # 0 should return 0, and False should return False diff --git a/test_spec.py b/test_spec.py index 56bdea6..d064ffe 100755 --- a/test_spec.py +++ b/test_spec.py @@ -1,6 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +import collections import unittest import os import json @@ -435,6 +436,18 @@ class ExpandedCoverage(unittest.TestCase): self.assertEqual(result, expected) + def test_namedtuple_data(self): + NT = collections.namedtuple('NT', ['foo', 'bar']) + args = { + 'template': '{{foo}} {{bar}}', + 'data': NT('hello', 'world') + } + + result = chevron.render(**args) + expected = 'hello world' + + self.assertEqual(result, expected) + # Run unit tests from command line if __name__ == "__main__":