From 01f94bda38b8f9956cfa1b227f2ebdb8ea2dfdd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Wed, 8 May 2002 08:44:21 +0000 Subject: 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. --- Doc/api/abstract.tex | 7 +++++++ Include/abstract.h | 6 ++++++ Misc/NEWS | 4 ++++ 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); /* diff --git a/Misc/NEWS b/Misc/NEWS index 34befe8..d31e09d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -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; } -- cgit v0.12