#2719: backport next() from 3k.
This commit is contained in:
parent
46d6b689b2
commit
28e0873f1f
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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},
|
||||
|
|
Loading…
Reference in New Issue