Index: Lib/unittest.py =================================================================== --- Lib/unittest.py (revision 71178) +++ Lib/unittest.py (working copy) @@ -858,9 +858,13 @@ # not hashable. expected = list(expected_seq) actual = list(actual_seq) - expected.sort() - actual.sort() - missing, unexpected = _SortedListDifference(expected, actual) + try: + expected.sort() + actual.sort() + except TypeError: + missing, unexpected = _UnorderableListDifference(expected, actual) + else: + missing, unexpected = _SortedListDifference(expected, actual) errors = [] if missing: errors.append('Expected, but missing:\n %r' % missing) @@ -985,6 +989,22 @@ break return missing, unexpected +def _UnorderableListDifference(expected, actual): + """Same behavior as _SortedListDifference but + for lists of unorderable items (like dicts). + + As it does a linear search per item (remove) it + has O(n*n) performance.""" + missing = [] + while expected: + item = expected.pop() + try: + actual.remove(item) + except ValueError: + missing.append(item) + + # anything left in actual is unexpected + return missing, actual class TestSuite(object): """A test suite is a composite test consisting of a number of TestCases. Index: Lib/test/test_unittest.py =================================================================== --- Lib/test/test_unittest.py (revision 71178) +++ Lib/test/test_unittest.py (working copy) @@ -2392,8 +2392,6 @@ self.assertRaises(self.failureException, self.assertEqual, a, b, msg='foo') - # The fact that dictionaries are unorderable breaks this test for them. - @unittest.expectedFailure def testEquality(self): self.assertListEqual([], []) self.assertTupleEqual((), ()) @@ -2459,6 +2457,8 @@ self.assertSameElements([{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 1}]) self.assertRaises(self.failureException, self.assertSameElements, [[1]], [[2]]) + self.assertRaises(self.failureException, self.assertSameElements, + [{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 2}]) def testAssertSetEqual(self): set1 = set()