How to test your __eq__ / __ne__ / __cmp__

In Python, a common mistake is to implement __eq__ on your object without also implementing __ne__. Even worse, your unit tests will often hide the error because the default object-identity __ne__ will probably satisfy your assertions.

If you’ve implemented __eq__ and __ne__, you might still have a mistake if the superclass has a __cmp__: Python’s cmp will fall back to the superclass’ __cmp__ instead of using your __eq__ (example). You’ll probably never notice this problem unless you use cmp(...) on your object.

When I need to exercise all possible combinations of ==, !=, and cmp, I mix this into my TestCases and use self.assertReally(Not)Equal(a, b):

class ReallyEqualMixin(object):
	def assertReallyEqual(self, a, b):
		# assertEqual first, because it will have a good message if the
		# assertion fails.
		self.assertEqual(a, b)
		self.assertEqual(b, a)
		self.assertTrue(a == b)
		self.assertTrue(b == a)
		self.assertFalse(a != b)
		self.assertFalse(b != a)
		self.assertEqual(0, cmp(a, b))
		self.assertEqual(0, cmp(b, a))
 
	def assertReallyNotEqual(self, a, b):
		# assertNotEqual first, because it will have a good message if the
		# assertion fails.
		self.assertNotEqual(a, b)
		self.assertNotEqual(b, a)
		self.assertFalse(a == b)
		self.assertFalse(b == a)
		self.assertTrue(a != b)
		self.assertTrue(b != a)
		self.assertNotEqual(0, cmp(a, b))
		self.assertNotEqual(0, cmp(b, a))

No © on the above, enjoy.

Further reading: How to override comparison operators in Python

3 Responses to “How to test your __eq__ / __ne__ / __cmp__”

  1. By Jeff on Nov 2nd, 2010 at 01:47

    Thanks for putting this out there.

  2. By uh on Nov 2nd, 2010 at 13:18

    If you dont know how to test __eq__, __ne__, or __cmp__, you probably shouldn’t be using it in your code

  3. By ivank on Nov 2nd, 2010 at 20:39

    Right, but half of my point was to gently remind people that __ne__ and __cmp__ exist. There’s a lot of buggy code out there already.