]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Teach set modules to correctly compute s-=s and s^=s as the empty set.
authorRaymond Hettinger <python@rcn.com>
Sat, 13 Aug 2005 02:28:54 +0000 (02:28 +0000)
committerRaymond Hettinger <python@rcn.com>
Sat, 13 Aug 2005 02:28:54 +0000 (02:28 +0000)
Lib/sets.py
Lib/test/test_set.py
Lib/test/test_sets.py
Misc/NEWS
Objects/setobject.c

index 8ec7e2fa8c50ec94929154b52656fd1a06556051..32a0dd64ff871dc15ef658b699096931c7afa405 100644 (file)
@@ -480,6 +480,8 @@ class Set(BaseSet):
         value = True
         if not isinstance(other, BaseSet):
             other = Set(other)
+        if self is other:
+            self.clear()
         for elt in other:
             if elt in data:
                 del data[elt]
@@ -497,6 +499,8 @@ class Set(BaseSet):
         data = self._data
         if not isinstance(other, BaseSet):
             other = Set(other)
+        if self is other:
+            self.clear()
         for elt in ifilter(data.has_key, other):
             del data[elt]
 
index b4c7c4f3f5c4479a0732c6c2a4153f1b11614313..354db7818d274620a9c31d18d19f24a0271298ca 100644 (file)
@@ -382,6 +382,18 @@ class TestSet(TestJointOps):
             else:
                 self.assert_(c not in self.s)
 
+    def test_inplace_on_self(self):
+        t = self.s.copy()
+        t |= t
+        self.assertEqual(t, self.s)
+        t &= t
+        self.assertEqual(t, self.s)
+        t -= t
+        self.assertEqual(t, self.thetype())
+        t = self.s.copy()
+        t ^= t
+        self.assertEqual(t, self.thetype())
+
     def test_weakref(self):
         s = self.thetype('gallahad')
         p = proxy(s)
index c5a48b1c1ec80d6221cbb0f4ac083d40ff342ebc..ff834e0aa0d7ab64e98c1f7b883c2e30713a32b3 100644 (file)
@@ -243,6 +243,19 @@ class TestBinaryOps(unittest.TestCase):
         self.assertRaises(TypeError, cmp, a, 12)
         self.assertRaises(TypeError, cmp, "abc", a)
 
+    def test_inplace_on_self(self):
+        t = self.set.copy()
+        t |= t
+        self.assertEqual(t, self.set)
+        t &= t
+        self.assertEqual(t, self.set)
+        t -= t
+        self.assertEqual(len(t), 0)
+        t = self.set.copy()
+        t ^= t
+        self.assertEqual(len(t), 0)
+
+
 #==============================================================================
 
 class TestUpdateOps(unittest.TestCase):
index 0e37a1e034b05896ce344e8f5df0f4f7d68f63d7..5d58ce923e84388a6b3d9343065f588678b877e4 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -17,6 +17,8 @@ Core and builtins
   __hash__() function.  Also, changed set.__contains__() to have
   identical logic.
 
+- The set() builtin can now properly compute s-=s as an empty set.
+
 - SF bug #1238681:  freed pointer is used in longobject.c:long_pow().
 
 - SF bug #1185883:  Python's small-object memory allocator took over
@@ -58,6 +60,8 @@ Extension Modules
 Library
 -------
 
+- The sets module can now properly compute s-=s and s^=s as an empty set.
+
 - Patch #827386: Support absolute source paths in msvccompiler.py.
 
 - Fix a problem in Tkinter introduced by SF patch #869468: delete bogus
index e77e7cd6f7405bf9b0af2c4466987b14200d72ea..0e653200894b88f46ea31d4448332e4ed2abe919 100644 (file)
@@ -192,6 +192,16 @@ frozenset_copy(PySetObject *so)
 
 PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
 
+static PyObject *
+set_clear(PySetObject *so)
+{
+       PyDict_Clear(so->data);
+       so->hash = -1;
+       Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
+
 static PyObject *
 set_union(PySetObject *so, PyObject *other)
 {
@@ -379,6 +389,9 @@ static PyObject *
 set_difference_update(PySetObject *so, PyObject *other)
 {
        PyObject *item, *tgtdata, *it;
+
+       if ((PyObject *)so == other)
+               return set_clear(so);
        
        it = PyObject_GetIter(other);
        if (it == NULL)
@@ -758,16 +771,6 @@ set_tp_print(PySetObject *so, FILE *fp, int flags)
        return 0;
 }
 
-static PyObject *
-set_clear(PySetObject *so)
-{
-       PyDict_Clear(so->data);
-       so->hash = -1;
-       Py_RETURN_NONE;
-}
-
-PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
-
 static int
 set_tp_clear(PySetObject *so)
 {