Index: Lib/unittest/test/test_case.py =================================================================== --- Lib/unittest/test/test_case.py (revision 86592) +++ Lib/unittest/test/test_case.py (working copy) @@ -712,6 +712,13 @@ self.assertRaises(self.failureException, self.assertItemsEqual, [1, {'b': 2}, None, True], [{'b': 2}, True, None]) + # Same elements which don't reliably compare, in + # different order, see issue 10242 + a = [{2,4}, {1,2}] + b = a[::-1] + self.assertItemsEqual(a, b) + + def testAssertSetEqual(self): set1 = set() set2 = set() Index: Lib/unittest/case.py =================================================================== --- Lib/unittest/case.py (revision 86592) +++ Lib/unittest/case.py (working copy) @@ -6,6 +6,7 @@ import pprint import re import warnings +import collections from . import result from .util import (strclass, safe_repr, sorted_list_difference, @@ -1002,8 +1003,8 @@ def assertItemsEqual(self, expected_seq, actual_seq, msg=None): """An unordered sequence / set specific comparison. It asserts that - expected_seq and actual_seq contain the same elements. It is - the equivalent of:: + expected_seq and actual_seq contain the same elements in the same + quantities. It is the equivalent of:: self.assertEqual(sorted(expected_seq), sorted(actual_seq)) @@ -1016,15 +1017,19 @@ - [0, 0, 1] and [0, 1] compare unequal. """ try: - expected = sorted(expected_seq) - actual = sorted(actual_seq) + expected_cnt = collections.Counter(iter(expected_seq)) + actual_cnt = collections.Counter(iter(actual_seq)) except TypeError: # Unsortable items (example: set(), complex(), ...) expected = list(expected_seq) actual = list(actual_seq) missing, unexpected = unorderable_list_difference(expected, actual) else: - return self.assertSequenceEqual(expected, actual, msg=msg) + if expected_cnt == actual_cnt: + return + else: + missing = [i for i in expected_cnt if expected_cnt[i] != actual_cnt[i]] + unexpected = [i for i in actual_cnt if actual_cnt[i] != expected_cnt[i]] errors = [] if missing: