diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 4ec03c84771..a1fd62784ef 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -710,6 +710,15 @@ available. They are listed here in alphabetical order. Added support for the optional *key* argument. +.. function:: next(iterator[, default]) + + Retrieve the next item from the *iterator* by calling its :meth:`next` + method. If *default* is given, it is returned if the iterator is exhausted, + otherwise :exc:`StopIteration` is raised. + + .. versionadded:: 2.6 + + .. function:: object() Return a new featureless object. :class:`object` is a base for all new style diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 9fa973ea026..dbc86e281aa 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -1539,6 +1539,33 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(min(data, key=f), sorted(data, key=f)[0]) + def test_next(self): + it = iter(range(2)) + self.assertEqual(next(it), 0) + self.assertEqual(next(it), 1) + self.assertRaises(StopIteration, next, it) + self.assertRaises(StopIteration, next, it) + self.assertEquals(next(it, 42), 42) + + class Iter(object): + def __iter__(self): + return self + def next(self): + raise StopIteration + + it = iter(Iter()) + self.assertEquals(next(it, 42), 42) + self.assertRaises(StopIteration, next, it) + + def gen(): + yield 1 + return + + it = gen() + self.assertEquals(next(it), 1) + self.assertRaises(StopIteration, next, it) + self.assertEquals(next(it, 42), 42) + def test_oct(self): self.assertEqual(oct(100), '0144') self.assertEqual(oct(100L), '0144L') diff --git a/Misc/NEWS b/Misc/NEWS index 501a164332a..34bdb9dfe91 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,8 @@ What's New in Python 2.6 alpha 3? Core and builtins ----------------- +- Issue #2719: backported the ``next()`` builtin from Python 3. + - Issue #2681: The octal literal ``0o8`` was incorrecly acctepted. Now it properly raises a SyntaxError. diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 9f9b75a7372..02a2faae3cd 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1070,6 +1070,47 @@ sequences have the same length. If the function is None, return a list of\n\ the items of the sequence (or a list of tuples if more than one sequence)."); +static PyObject * +builtin_next(PyObject *self, PyObject *args) +{ + PyObject *it, *res; + PyObject *def = NULL; + + if (!PyArg_UnpackTuple(args, "next", 1, 2, &it, &def)) + return NULL; + if (!PyIter_Check(it)) { + PyErr_Format(PyExc_TypeError, + "%.200s object is not an iterator", + it->ob_type->tp_name); + return NULL; + } + + res = (*it->ob_type->tp_iternext)(it); + if (res != NULL) { + return res; + } else if (def != NULL) { + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) + return NULL; + PyErr_Clear(); + } + Py_INCREF(def); + return def; + } else if (PyErr_Occurred()) { + return NULL; + } else { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } +} + +PyDoc_STRVAR(next_doc, +"next(iterator[, default])\n\ +\n\ +Return the next item from the iterator. If default is given and the iterator\n\ +is exhausted, it is returned instead of raising StopIteration."); + + static PyObject * builtin_setattr(PyObject *self, PyObject *args) { @@ -2509,6 +2550,7 @@ static PyMethodDef builtin_methods[] = { {"map", builtin_map, METH_VARARGS, map_doc}, {"max", (PyCFunction)builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, {"min", (PyCFunction)builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, + {"next", builtin_next, METH_VARARGS, next_doc}, {"oct", builtin_oct, METH_O, oct_doc}, {"open", (PyCFunction)builtin_open, METH_VARARGS | METH_KEYWORDS, open_doc}, {"ord", builtin_ord, METH_O, ord_doc},