Let set.union() and set.update() accept multiple inputs.
authorRaymond Hettinger <python@rcn.com>
Mon, 9 Jun 2008 08:33:37 +0000 (08:33 +0000)
committerRaymond Hettinger <python@rcn.com>
Mon, 9 Jun 2008 08:33:37 +0000 (08:33 +0000)
Doc/library/stdtypes.rst
Lib/test/test_set.py
Misc/NEWS
Objects/setobject.c

index c96ef10d7bb2cf666fe7b3e417ff3e44b96bd5c4..1d8e053609df92b3e98e64298a86f43d86045421 100644 (file)
@@ -1567,11 +1567,14 @@ The constructors for both classes work the same:
       Test whether the set is a true superset of *other*, that is, ``set >=
       other and set != other``.
 
-   .. method:: union(other)
-               set | other
+   .. method:: union(other, ...)
+               set | other | ...
 
       Return a new set with elements from both sets.
 
+      .. versionchanged:: 2.6
+         Accepts multiple input iterables.
+
    .. method:: intersection(other)
                set & other
 
@@ -1628,11 +1631,14 @@ The constructors for both classes work the same:
    The following table lists operations available for :class:`set` that do not
    apply to immutable instances of :class:`frozenset`:
 
-   .. method:: update(other)
-               set |= other
+   .. method:: update(other, ...)
+               set |= other | ...
 
       Update the set, adding elements from *other*.
 
+      .. versionchanged:: 2.6
+         Accepts multiple input iterables.
+
    .. method:: intersection_update(other)
                set &= other
 
index 6b3df3dd653259db3d5b64b5d4759bf33f6fdd5b..37a085cf77c8e7256f7764ae10a761f3dc15c441 100644 (file)
@@ -78,6 +78,7 @@ class TestJointOps(unittest.TestCase):
             self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
             self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
             self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
+            self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
 
     def test_or(self):
         i = self.s.union(self.otherword)
@@ -401,6 +402,12 @@ class TestSet(TestJointOps):
                 s = self.thetype('abcba')
                 self.assertEqual(s.update(C(p)), None)
                 self.assertEqual(s, set(q))
+        for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
+            q = 'ahi'
+            for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
+                s = self.thetype('abcba')
+                self.assertEqual(s.update(C(p), C(q)), None)
+                self.assertEqual(s, set(s) | set(p) | set(q))
 
     def test_ior(self):
         self.s |= set(self.otherword)
index 4337e5daff9f32d66141d7cf28234b0fa0ec5d0a..05f741975af1be69ebacfbad560ff25801a54655 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 2.6 beta 1?
 Core and Builtins
 -----------------
 
+- The set methods, update() and union() now accept multiple arguments.
+
 - Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
 
 - New environment variable PYTHONIOENCODING.
index 371d8c154177ec4cba34a59910143b747c4f735b..908a9a3d0978c825d7c48dd92ca1253429412750 100644 (file)
@@ -967,15 +967,20 @@ set_update_internal(PySetObject *so, PyObject *other)
 }
 
 static PyObject *
-set_update(PySetObject *so, PyObject *other)
+set_update(PySetObject *so, PyObject *args)
 {
-       if (set_update_internal(so, other) == -1)
-               return NULL;
+       Py_ssize_t i;
+
+       for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+               PyObject *other = PyTuple_GET_ITEM(args, i);
+               if (set_update_internal(so, other) == -1)
+                       return NULL;
+       }
        Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(update_doc, 
-"Update a set with the union of itself and another.");
+"Update a set with the union of itself and others.");
 
 static PyObject *
 make_new_set(PyTypeObject *type, PyObject *iterable)
@@ -1156,35 +1161,53 @@ set_clear(PySetObject *so)
 PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
 
 static PyObject *
-set_union(PySetObject *so, PyObject *other)
+set_union(PySetObject *so, PyObject *args)
 {
        PySetObject *result;
+       PyObject *other;
+       Py_ssize_t i;
 
        result = (PySetObject *)set_copy(so);
        if (result == NULL)
                return NULL;
-       if ((PyObject *)so == other)
-               return (PyObject *)result;
-       if (set_update_internal(result, other) == -1) {
-               Py_DECREF(result);
-               return NULL;
+
+       for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+               other = PyTuple_GET_ITEM(args, i);
+               if ((PyObject *)so == other)
+                       return (PyObject *)result;
+               if (set_update_internal(result, other) == -1) {
+                       Py_DECREF(result);
+                       return NULL;
+               }
        }
        return (PyObject *)result;
 }
 
 PyDoc_STRVAR(union_doc,
- "Return the union of two sets as a new set.\n\
+ "Return the union of sets as a new set.\n\
 \n\
 (i.e. all elements that are in either set.)");
 
 static PyObject *
 set_or(PySetObject *so, PyObject *other)
 {
+       PySetObject *result;
+
        if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
                Py_INCREF(Py_NotImplemented);
                return Py_NotImplemented;
        }
-       return set_union(so, other);
+
+       result = (PySetObject *)set_copy(so);
+       if (result == NULL)
+               return NULL;
+       if ((PyObject *)so == other)
+               return (PyObject *)result;
+       if (set_update_internal(result, other) == -1) {
+               Py_DECREF(result);
+               return NULL;
+       }
+       return (PyObject *)result;
 }
 
 static PyObject *
@@ -1947,9 +1970,9 @@ static PyMethodDef set_methods[] = {
        {"test_c_api",  (PyCFunction)test_c_api,        METH_NOARGS,
         test_c_api_doc},
 #endif
-       {"union",       (PyCFunction)set_union,         METH_O,
+       {"union",       (PyCFunction)set_union,         METH_VARARGS,
         union_doc},
-       {"update",      (PyCFunction)set_update,        METH_O,
+       {"update",      (PyCFunction)set_update,        METH_VARARGS,
         update_doc},
        {NULL,          NULL}   /* sentinel */
 };
@@ -2062,7 +2085,7 @@ static PyMethodDef frozenset_methods[] = {
         reduce_doc},
        {"symmetric_difference",(PyCFunction)set_symmetric_difference,  METH_O,
         symmetric_difference_doc},
-       {"union",       (PyCFunction)set_union,         METH_O,
+       {"union",       (PyCFunction)set_union,         METH_VARARGS,
         union_doc},
        {NULL,          NULL}   /* sentinel */
 };