views:

32

answers:

1

I have a unit test for my GAE app:

def test_getNeighborhoodKeys_twoCourses(self):
            cs1110, cs2110 = testutils.setUpSimpleCourses()

            foo = getFooResult()
            bar = getBarResult()

    self.assertEquals(foo, bar) # fails

This is the failure:

AssertionError: set([CS 1110: Untitled, CS 2110: Untitled]) != set([CS 2110: Untitled, CS 1110: Untitled])

It looks to me like the test should pass. What's going wrong?

+4  A: 

Looks like the items belonging to sets foo and bar are of some extremely funky type which overrides __repr__ -- otherwise, with normal types, there would be quotes to clarify exactly what's inside those brackets. Thus, that type must also override __eq__ to determine equality conditions (otherwise, by default, two instances are equal only if they're the same instance). You could alternatively override __cmp__, but that's a pretty old and dusty approach -- specific comparisons such as __eq__ are vastly preferred nowadays!

If you do override __eq__ (or __cmp__ for that matter) be sure to also override __hash__ because it's crucial that two instances that compare equal have exactly the same hash too, otherwise use of such instances as members of sets, or keys in dictionaries, misbehaves in very hard to predict ways.

Alex Martelli
Actually, I overrode `__repr__` myself to make debugging easier. Was that a poor decision? What if I were to override `__str__`? Could I then leave `__eq__` and `__hash__` alone?
Rosarch
@Rosarch, you need to override `__eq__` (and `__hash__` possibly) whenever you want instances of a user-coded type to be able to compare equal without being identical (i.e., the same instance) -- the only reason I mentioned the override of `__repr__` is because that what can be immediately spotted in the message you showed, and proves the instances belong to some funky type and aren't exactly the same instance, **not** because that override has anything to do with equality-testing per se.
Alex Martelli