Patch #552433: Special-case tuples. Avoid sub-type checking for lists.

Avoid checks for negative indices and duplicate checks for support of
the sequence protocol.
This commit is contained in:
Martin v. Löwis 2002-05-08 08:44:21 +00:00
parent 000e37c3c4
commit 01f94bda38
4 changed files with 35 additions and 2 deletions

View file

@ -765,6 +765,13 @@ determination.
and that \var{i} is within bounds. and that \var{i} is within bounds.
\end{cfuncdesc} \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} \begin{cfuncdesc}{int}{PySequence_Fast_GET_SIZE}{PyObject *o}
Returns the length of \var{o}, assuming that \var{o} was Returns the length of \var{o}, assuming that \var{o} was
returned by \cfunction{PySequence_Fast()} and that \var{o} is returned by \cfunction{PySequence_Fast()} and that \var{o} is

View file

@ -1015,6 +1015,12 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
PySequence_Fast, and that i is within bounds. 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); DL_IMPORT(int) PySequence_Count(PyObject *o, PyObject *value);
/* /*

View file

@ -192,6 +192,10 @@ Build
C API 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. - PyRange_New() now raises ValueError if the fourth argument is not 1.
This is part of the removal of deprecated features of the xrange This is part of the removal of deprecated features of the xrange
object. object.

View file

@ -12,6 +12,11 @@ PyObject *
PySeqIter_New(PyObject *seq) PySeqIter_New(PyObject *seq)
{ {
seqiterobject *it; seqiterobject *it;
if (!PySequence_Check(seq)) {
PyErr_BadInternalCall();
return NULL;
}
it = PyObject_GC_New(seqiterobject, &PySeqIter_Type); it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);
if (it == NULL) if (it == NULL)
return NULL; return NULL;
@ -63,7 +68,7 @@ iter_iternext(PyObject *iterator)
it = (seqiterobject *)iterator; it = (seqiterobject *)iterator;
seq = it->it_seq; seq = it->it_seq;
if (PyList_Check(seq)) { if (PyList_CheckExact(seq)) {
PyObject *item; PyObject *item;
if (it->it_index >= PyList_GET_SIZE(seq)) { if (it->it_index >= PyList_GET_SIZE(seq)) {
return NULL; return NULL;
@ -73,8 +78,19 @@ iter_iternext(PyObject *iterator)
Py_INCREF(item); Py_INCREF(item);
return 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 { else {
PyObject *result = PySequence_GetItem(seq, it->it_index++); PyObject *result = PySequence_ITEM(seq, it->it_index);
it->it_index++;
if (result != NULL) { if (result != NULL) {
return result; return result;
} }