diff --git a/django/utils/functional.py b/django/utils/functional.py index 9635bf92a6..21463bd575 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -68,14 +68,15 @@ def lazy(func, *resultclasses): cls.__dispatch = {} for resultclass in resultclasses: cls.__dispatch[resultclass] = {} - for (k, v) in resultclass.__dict__.items(): - # All __promise__ return the same wrapper method, but they - # also do setup, inserting the method into the dispatch - # dict. - meth = cls.__promise__(resultclass, k, v) - if hasattr(cls, k): - continue - setattr(cls, k, meth) + for type_ in reversed(resultclass.mro()): + for (k, v) in type_.__dict__.items(): + # All __promise__ return the same wrapper method, but they + # also do setup, inserting the method into the dispatch + # dict. + meth = cls.__promise__(resultclass, k, v) + if hasattr(cls, k): + continue + setattr(cls, k, meth) cls._delegate_str = str in resultclasses cls._delegate_unicode = unicode in resultclasses assert not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types." diff --git a/tests/regressiontests/utils/functional.py b/tests/regressiontests/utils/functional.py index 763d6964c1..2784ddd7be 100644 --- a/tests/regressiontests/utils/functional.py +++ b/tests/regressiontests/utils/functional.py @@ -7,3 +7,16 @@ class FunctionalTestCase(unittest.TestCase): t = lazy(lambda: tuple(range(3)), list, tuple) for a, b in zip(t(), range(3)): self.assertEqual(a, b) + + def test_lazy_base_class(self): + """Test that lazy also finds base class methods in the proxy object""" + + class Base(object): + def base_method(self): + pass + + class Klazz(Base): + pass + + t = lazy(lambda: Klazz(), Klazz)() + self.assertTrue('base_method' in dir(t))