summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/lib/libfuncs.tex26
-rw-r--r--Lib/test/test_builtin.py36
-rw-r--r--Misc/NEWS2
-rw-r--r--Python/bltinmodule.c65
4 files changed, 129 insertions, 0 deletions
diff --git a/Doc/lib/libfuncs.tex b/Doc/lib/libfuncs.tex
index 6b853f3..9e387d9 100644
--- a/Doc/lib/libfuncs.tex
+++ b/Doc/lib/libfuncs.tex
@@ -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
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 5aa9197..4e8ffe5 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -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, ())
diff --git a/Misc/NEWS b/Misc/NEWS
index 3f4cbb1..19ce8f4 100644
--- 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)
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 33b5ca5..145e946 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -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},