Opened 10 years ago

Closed 9 years ago

#23346 closed Bug (fixed)

django.utils.functional.lazy picks the wrong method implementation

Reported by: Gavin Wahl Owned by: nobody
Component: Core (Other) Version: 1.6
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When a subclass of resultclasses is returned by the wrapped function, method implementaions are looked up on the base class (the one in resultclasses), not on the object actually returned.

    def test_lazy_base_class_override(self):
        """Test that lazy finds the correct (overridden) method implementation"""

        class Base(object):
            def method(self):
                return 'Base'

        class Klazz(Base):
            def method(self):
                return 'Klazz'

        t = lazy(lambda: Klazz(), Base)()
        self.assertEqual(t.method(), 'Klazz')

In the current implementation, Base.method will be called, not Klazz.method.

Change History (3)

comment:1 by Gavin Wahl, 10 years ago

Has patch: set

https://github.com/django/django/pull/3104

This makes the code easier to understand, in my opinion. I couldn't figure out why methods were being pulled off of resultclasses when the real object is available. This patch simplifies the situation and gets rid of the __dispatch table completely.

comment:2 by Claude Paroz, 10 years ago

Component: UncategorizedCore (Other)
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug

I think if we can simplify and fix lazy, it is a good thing. However, as it is a bit magic code, it would be nice if it could still be reviewed by a Python guru.

comment:3 by Tim Graham <timograham@…>, 9 years ago

Resolution: fixed
Status: newclosed

In b4e76f30d12bfa8a53cc297c60055c6f4629cc4c:

Fixed #23346 -- Fixed lazy() to lookup methods on the real object, not resultclasses.

Co-Authored-By: Rocky Meza <rmeza@…>

Note: See TracTickets for help on using tickets.
Back to Top