Index: Objects/setobject.c =================================================================== --- Objects/setobject.c (revision 81048) +++ Objects/setobject.c (working copy) @@ -1476,9 +1476,25 @@ setentry *entry; Py_ssize_t pos = 0; - while (set_next((PySetObject *)other, &pos, &entry)) - if (set_discard_entry(so, entry) == -1) - return -1; + if (PySet_GET_SIZE(so) < PySet_GET_SIZE(other) ) { + while (set_next(so, &pos, &entry)) { + int rv = set_contains_entry((PySetObject *)other, entry); + if (rv == -1) + return -1; + if (rv == 1) { + PyObject *old_key; + old_key = entry->key; + Py_INCREF(dummy); + entry->key = dummy; + so->used--; + Py_DECREF(old_key); + } + } + } else { + while (set_next((PySetObject *)other, &pos, &entry)) + if (set_discard_entry(so, entry) == -1) + return -1; + } } else { PyObject *key, *it; it = PyObject_GetIter(other); Index: Lib/test/test_set.py =================================================================== --- Lib/test/test_set.py (revision 81048) +++ Lib/test/test_set.py (working copy) @@ -973,87 +973,110 @@ class TestUpdateOps(unittest.TestCase): def setUp(self): - self.set = set((2, 4, 6)) + self.saved_set = self.set = set((2, 4, 6)) + def assert_updated_inplace(self): + self.assertIs(self.saved_set, self.set) + def test_union_subset(self): self.set |= set([2]) self.assertEqual(self.set, set((2, 4, 6))) + self.assert_updated_inplace() def test_union_superset(self): self.set |= set([2, 4, 6, 8]) self.assertEqual(self.set, set([2, 4, 6, 8])) + self.assert_updated_inplace() def test_union_overlap(self): self.set |= set([3, 4, 5]) self.assertEqual(self.set, set([2, 3, 4, 5, 6])) + self.assert_updated_inplace() def test_union_non_overlap(self): self.set |= set([8]) self.assertEqual(self.set, set([2, 4, 6, 8])) + self.assert_updated_inplace() def test_union_method_call(self): self.set.update(set([3, 4, 5])) self.assertEqual(self.set, set([2, 3, 4, 5, 6])) + self.assert_updated_inplace() def test_intersection_subset(self): self.set &= set((2, 4)) self.assertEqual(self.set, set((2, 4))) + self.assert_updated_inplace() def test_intersection_superset(self): self.set &= set([2, 4, 6, 8]) self.assertEqual(self.set, set([2, 4, 6])) + self.assert_updated_inplace() def test_intersection_overlap(self): self.set &= set([3, 4, 5]) self.assertEqual(self.set, set([4])) + self.assert_updated_inplace() def test_intersection_non_overlap(self): self.set &= set([8]) self.assertEqual(self.set, empty_set) + self.assert_updated_inplace() def test_intersection_method_call(self): self.set.intersection_update(set([3, 4, 5])) self.assertEqual(self.set, set([4])) + self.assert_updated_inplace() def test_sym_difference_subset(self): self.set ^= set((2, 4)) self.assertEqual(self.set, set([6])) + self.assert_updated_inplace() def test_sym_difference_superset(self): self.set ^= set((2, 4, 6, 8)) self.assertEqual(self.set, set([8])) + self.assert_updated_inplace() def test_sym_difference_overlap(self): self.set ^= set((3, 4, 5)) self.assertEqual(self.set, set([2, 3, 5, 6])) + self.assert_updated_inplace() def test_sym_difference_non_overlap(self): self.set ^= set([8]) self.assertEqual(self.set, set([2, 4, 6, 8])) + self.assert_updated_inplace() def test_sym_difference_method_call(self): self.set.symmetric_difference_update(set([3, 4, 5])) self.assertEqual(self.set, set([2, 3, 5, 6])) + self.assert_updated_inplace() def test_difference_subset(self): self.set -= set((2, 4)) self.assertEqual(self.set, set([6])) + self.assert_updated_inplace() def test_difference_superset(self): self.set -= set((2, 4, 6, 8)) self.assertEqual(self.set, set([])) + self.assert_updated_inplace() def test_difference_overlap(self): self.set -= set((3, 4, 5)) self.assertEqual(self.set, set([2, 6])) + self.assert_updated_inplace() def test_difference_non_overlap(self): self.set -= set([8]) self.assertEqual(self.set, set([2, 4, 6])) + self.assert_updated_inplace() def test_difference_method_call(self): self.set.difference_update(set([3, 4, 5])) self.assertEqual(self.set, set([2, 6])) + self.assert_updated_inplace() #==============================================================================