diff options
-rw-r--r-- | Doc/api/abstract.tex | 7 | ||||
-rw-r--r-- | Include/abstract.h | 6 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Objects/iterobject.c | 20 |
4 files changed, 35 insertions, 2 deletions
diff --git a/Doc/api/abstract.tex b/Doc/api/abstract.tex index 0e25afa..e4f299d 100644 --- a/Doc/api/abstract.tex +++ b/Doc/api/abstract.tex @@ -765,6 +765,13 @@ determination. and that \var{i} is within bounds. \end{cfuncdesc} +\begin{cfuncdesc}{PyObject*}{PySequence_ITEM}{PyObject *o, int i} + Return the \var{i}th element of \var{o} or \NULL on failure. + Macro form of \cfunction{PySequence_GetItem()} but without checking + that \cfunction{PySequence_Check(\var{o})} is true and without + adjustment for negative indices. +\end{cfuncdesc} + \begin{cfuncdesc}{int}{PySequence_Fast_GET_SIZE}{PyObject *o} Returns the length of \var{o}, assuming that \var{o} was returned by \cfunction{PySequence_Fast()} and that \var{o} is diff --git a/Include/abstract.h b/Include/abstract.h index 226e5e8..459bd56 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -1015,6 +1015,12 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ PySequence_Fast, and that i is within bounds. */ +#define PySequence_ITEM(o, i)\ + ( o->ob_type->tp_as_sequence->sq_item(o, i) ) + /* Assume tp_as_sequence and sq_item exist and that i does not + need to be corrected for a negative index + */ + DL_IMPORT(int) PySequence_Count(PyObject *o, PyObject *value); /* @@ -192,6 +192,10 @@ Build C API +- Added new macro PySequence_ITEM(o, i) that directly calls + sq_item without rechecking that o is a sequence and without + adjusting for negative indices. + - PyRange_New() now raises ValueError if the fourth argument is not 1. This is part of the removal of deprecated features of the xrange object. diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 789eb6c..de9f2f9 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -12,6 +12,11 @@ PyObject * PySeqIter_New(PyObject *seq) { seqiterobject *it; + + if (!PySequence_Check(seq)) { + PyErr_BadInternalCall(); + return NULL; + } it = PyObject_GC_New(seqiterobject, &PySeqIter_Type); if (it == NULL) return NULL; @@ -63,7 +68,7 @@ iter_iternext(PyObject *iterator) it = (seqiterobject *)iterator; seq = it->it_seq; - if (PyList_Check(seq)) { + if (PyList_CheckExact(seq)) { PyObject *item; if (it->it_index >= PyList_GET_SIZE(seq)) { return NULL; @@ -73,8 +78,19 @@ iter_iternext(PyObject *iterator) Py_INCREF(item); return item; } + if (PyTuple_CheckExact(seq)) { + PyObject *item; + if (it->it_index >= PyTuple_GET_SIZE(seq)) { + return NULL; + } + item = PyTuple_GET_ITEM(seq, it->it_index); + it->it_index++; + Py_INCREF(item); + return item; + } else { - PyObject *result = PySequence_GetItem(seq, it->it_index++); + PyObject *result = PySequence_ITEM(seq, it->it_index); + it->it_index++; if (result != NULL) { return result; } |