﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
17466	Model __eq__ does not compare correctly between normal objects and deferred objects	Raphaël Hertzog <hertzog@…>	nobody	"Enrico Zini <enrico@debian.org> found a problem and reported it to the Debian Bug Tracking System: http://bugs.debian.org/653177

I'll paste his report below:

----

I noticed that there is a problem with the default model object {{{__eq__}}}
implementation when working with deferred objects.

The default implementation should be something like:

{{{
        def __eq__(self, other):
            return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_
val()
}}}

Now, given a simple model...

{{{
        class Package(models.Model):
                name = models.TextField(null=False, unique=True)
                # Lots of other fields
}}}

...this code will show the problem:

{{{
        # Get a normal object
        p = Package.objects.get(name=""debtags"")
        # Get a deferred object
        dp = Package.objects.filter(name=""debtags"").only(""name"")[0]
        print object.__repr__(p), hash(p)
        print object.__repr__(dp), hash(dp)
        # This assert succeeds
        assert hash(p) == hash(dp)
        # This assert fails
        assert p == dp
}}}

Its output is:

{{{
        <Package: debtags> 11
        <Package_Deferred_ldesc_popcon_sdesc_source_version: debtags> 11
}}}

It looks like the isinstance bit of the default {{{__eq__}}} model is failing
here.

This causes suprising behaviour:
{{{
        allpkgs = set(Package.objects.all().only(""name""))
        # This assert fails
        assert Package.objects.get(name=""debtags"") in allpkgs
}}}

"	Bug	closed	Uncategorized	1.3	Normal	duplicate		Enrico Zini <enrico@…> marti@…	Unreviewed	0	0	0	0	0	0
