# HG changeset patch # User cmlenz # Date 1206955826 0 # Node ID e5b0d9d6b406e471be90283cf9dee2eb5d5cea90 # Parent 08f22328303d4e05bd7186e5c8fe6257fdc18214 Improve error reporting when accessing an attribute in a Python expression raises an `AttributeError`. Closes #191. Thanks to Michele Cella for the patch! diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -69,6 +69,8 @@ content in memory, which could cause excessive memory use on long pages. The buffering can be disabled using the new `buffer` optimization hint on the `` directive. + * Improve error reporting when accessing an attribute in a Python expression + raises an `AttributeError` (ticket #191). Version 0.4.4 diff --git a/genshi/template/eval.py b/genshi/template/eval.py --- a/genshi/template/eval.py +++ b/genshi/template/eval.py @@ -271,12 +271,16 @@ def lookup_attr(cls, obj, key): __traceback_hide__ = True - val = getattr(obj, key, UNDEFINED) - if val is UNDEFINED: - try: - val = obj[key] - except (KeyError, TypeError): - val = cls.undefined(key, owner=obj) + try: + val = getattr(obj, key) + except AttributeError: + if hasattr(obj.__class__, key): + raise + else: + try: + val = obj[key] + except (KeyError, TypeError): + val = cls.undefined(key, owner=obj) return val lookup_attr = classmethod(lookup_attr) diff --git a/genshi/template/tests/eval.py b/genshi/template/tests/eval.py --- a/genshi/template/tests/eval.py +++ b/genshi/template/tests/eval.py @@ -342,11 +342,16 @@ def test_getattr_exception(self): class Something(object): - def prop(self): + def prop_a(self): raise NotImplementedError - prop = property(prop) + prop_a = property(prop_a) + def prop_b(self): + raise AttributeError + prop_b = property(prop_b) self.assertRaises(NotImplementedError, - Expression('s.prop').evaluate, {'s': Something()}) + Expression('s.prop_a').evaluate, {'s': Something()}) + self.assertRaises(AttributeError, + Expression('s.prop_b').evaluate, {'s': Something()}) def test_getitem_undefined_string(self): class Something(object):