]> granicus.if.org Git - python/commitdiff
Add two new functions, any() and all().
authorRaymond Hettinger <python@rcn.com>
Fri, 11 Mar 2005 06:49:40 +0000 (06:49 +0000)
committerRaymond Hettinger <python@rcn.com>
Fri, 11 Mar 2005 06:49:40 +0000 (06:49 +0000)
Doc/lib/libfuncs.tex
Lib/test/test_builtin.py
Misc/NEWS
Python/bltinmodule.c

index 6b853f3d02b953c9ff5310811334d95aa346df4e..9e387d9accd33bb95b6d6029258773cc9c094b56 100644 (file)
@@ -60,6 +60,32 @@ def my_import(name):
   complex number, its magnitude is returned.
 \end{funcdesc}
 
+\begin{funcdesc}{all}{iterable}
+  Return True if all elements of the \var{iterable} are true.
+  Equivalent to:
+  \begin{verbatim}
+     def all(iterable):
+         for element in iterable:
+             if not element:
+                 return False
+         return True
+  \end{verbatim}
+  \versionadded{2.5}
+\end{funcdesc}
+
+\begin{funcdesc}{any}{iterable}
+  Return True if any element of the \var{iterable} is true.
+  Equivalent to:
+  \begin{verbatim}
+     def any(iterable):
+         for element in iterable:
+             if element:
+                 return True
+         return False
+  \end{verbatim}
+  \versionadded{2.5}
+\end{funcdesc}
+
 \begin{funcdesc}{basestring}{}
   This abstract type is the superclass for \class{str} and \class{unicode}.
   It cannot be called or instantiated, but it can be used to test whether
index 5aa919732784fb42197b27a3971509551959db6d..4e8ffe5337ffa3e62c03060c0b8b6ba8f2a6b59e 100644 (file)
@@ -92,6 +92,14 @@ if have_unicode:
         (unichr(0x200), ValueError),
 ]
 
+class TestFailingBool:
+    def __nonzero__(self):
+        raise RuntimeError
+
+class TestFailingIter:
+    def __iter__(self):
+        raise RuntimeError
+
 class BuiltinTest(unittest.TestCase):
 
     def test_import(self):
@@ -117,6 +125,34 @@ class BuiltinTest(unittest.TestCase):
         # str
         self.assertRaises(TypeError, abs, 'a')
 
+    def test_all(self):
+        self.assertEqual(all([2, 4, 6]), True)
+        self.assertEqual(all([2, None, 6]), False)
+        self.assertRaises(RuntimeError, all, [2, TestFailingBool(), 6])
+        self.assertRaises(RuntimeError, all, TestFailingIter())
+        self.assertRaises(TypeError, all, 10)               # Non-iterable
+        self.assertRaises(TypeError, all)                   # No args
+        self.assertRaises(TypeError, all, [2, 4, 6], [])    # Too many args
+        self.assertEqual(all([]), True)                     # Empty iterator
+        S = [50, 60]
+        self.assertEqual(all(x > 42 for x in S), True)
+        S = [50, 40, 60]
+        self.assertEqual(all(x > 42 for x in S), False)
+
+    def test_any(self):
+        self.assertEqual(any([None, None, None]), False)
+        self.assertEqual(any([None, 4, None]), True)
+        self.assertRaises(RuntimeError, any, [None, TestFailingBool(), 6])
+        self.assertRaises(RuntimeError, all, TestFailingIter())
+        self.assertRaises(TypeError, any, 10)               # Non-iterable
+        self.assertRaises(TypeError, any)                   # No args
+        self.assertRaises(TypeError, any, [2, 4, 6], [])    # Too many args
+        self.assertEqual(any([]), False)                    # Empty iterator
+        S = [40, 60, 30]
+        self.assertEqual(any(x > 42 for x in S), True)
+        S = [10, 20, 30]
+        self.assertEqual(any(x > 42 for x in S), False)
+
     def test_apply(self):
         def f0(*args):
             self.assertEqual(args, ())
index 3f4cbb1250650cee985f54a1cdc182caa9f50a9e..19ce8f43ec6eaf0ba20ebee6a4c3b4eaf5442dae 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ What's New in Python 2.5 alpha 1?
 Core and builtins
 -----------------
 
+- Added two new builtins, any() and all().
+
 - Defining a class with empty parentheses is now allowed
   (e.g., ``class C(): pass`` is no longer a syntax error)
 
index 33b5ca5e46a32a48963a8c65928aae95638e52b9..145e9460f1d924f2ac248d0cc99a2f23d3417c6f 100644 (file)
@@ -68,6 +68,69 @@ PyDoc_STRVAR(abs_doc,
 \n\
 Return the absolute value of the argument.");
 
+static PyObject *
+builtin_all(PyObject *self, PyObject *v)
+{
+       PyObject *it, *item;
+
+       it = PyObject_GetIter(v);
+       if (it == NULL)
+               return NULL;
+
+       while ((item = PyIter_Next(it)) != NULL) {
+               int cmp = PyObject_IsTrue(item);
+               Py_DECREF(item);
+               if (cmp < 0) {
+                       Py_DECREF(it);
+                       return NULL;
+               }
+               if (cmp == 0) {
+                       Py_DECREF(it);
+                       Py_RETURN_FALSE;
+               }
+       }
+       Py_DECREF(it);
+       if (PyErr_Occurred())
+               return NULL;
+       Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(all_doc,
+"all(iterable) -> bool\n\
+\n\
+Return True if bool(x) is True for all values x in the iterable.");
+
+static PyObject *
+builtin_any(PyObject *self, PyObject *v)
+{
+       PyObject *it, *item;
+
+       it = PyObject_GetIter(v);
+       if (it == NULL)
+               return NULL;
+
+       while ((item = PyIter_Next(it)) != NULL) {
+               int cmp = PyObject_IsTrue(item);
+               Py_DECREF(item);
+               if (cmp < 0) {
+                       Py_DECREF(it);
+                       return NULL;
+               }
+               if (cmp == 1) {
+                       Py_DECREF(it);
+                       Py_RETURN_TRUE;
+               }
+       }
+       Py_DECREF(it);
+       if (PyErr_Occurred())
+               return NULL;
+       Py_RETURN_FALSE;
+}
+
+PyDoc_STRVAR(any_doc,
+"any(iterable) -> bool\n\
+\n\
+Return True if bool(x) is True for any x in the iterable.");
 
 static PyObject *
 builtin_apply(PyObject *self, PyObject *args)
@@ -2125,6 +2188,8 @@ in length to the length of the shortest argument sequence.");
 static PyMethodDef builtin_methods[] = {
        {"__import__",  builtin___import__, METH_VARARGS, import_doc},
        {"abs",         builtin_abs,        METH_O, abs_doc},
+       {"all",         builtin_all,        METH_O, all_doc},
+       {"any",         builtin_any,        METH_O, any_doc},
        {"apply",       builtin_apply,      METH_VARARGS, apply_doc},
        {"callable",    builtin_callable,   METH_O, callable_doc},
        {"chr",         builtin_chr,        METH_VARARGS, chr_doc},