Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 01f94bd

Browse files
committed
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.
1 parent 000e37c commit 01f94bd

4 files changed

Lines changed: 35 additions & 2 deletions

File tree

Doc/api/abstract.tex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,13 @@ \section{Sequence Protocol \label{sequence}}
765765
and that \var{i} is within bounds.
766766
\end{cfuncdesc}
767767

768+
\begin{cfuncdesc}{PyObject*}{PySequence_ITEM}{PyObject *o, int i}
769+
Return the \var{i}th element of \var{o} or \NULL on failure.
770+
Macro form of \cfunction{PySequence_GetItem()} but without checking
771+
that \cfunction{PySequence_Check(\var{o})} is true and without
772+
adjustment for negative indices.
773+
\end{cfuncdesc}
774+
768775
\begin{cfuncdesc}{int}{PySequence_Fast_GET_SIZE}{PyObject *o}
769776
Returns the length of \var{o}, assuming that \var{o} was
770777
returned by \cfunction{PySequence_Fast()} and that \var{o} is

Include/abstract.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,12 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
10151015
PySequence_Fast, and that i is within bounds.
10161016
*/
10171017

1018+
#define PySequence_ITEM(o, i)\
1019+
( o->ob_type->tp_as_sequence->sq_item(o, i) )
1020+
/* Assume tp_as_sequence and sq_item exist and that i does not
1021+
need to be corrected for a negative index
1022+
*/
1023+
10181024
DL_IMPORT(int) PySequence_Count(PyObject *o, PyObject *value);
10191025

10201026
/*

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ Build
192192

193193
C API
194194

195+
- Added new macro PySequence_ITEM(o, i) that directly calls
196+
sq_item without rechecking that o is a sequence and without
197+
adjusting for negative indices.
198+
195199
- PyRange_New() now raises ValueError if the fourth argument is not 1.
196200
This is part of the removal of deprecated features of the xrange
197201
object.

Objects/iterobject.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ PyObject *
1212
PySeqIter_New(PyObject *seq)
1313
{
1414
seqiterobject *it;
15+
16+
if (!PySequence_Check(seq)) {
17+
PyErr_BadInternalCall();
18+
return NULL;
19+
}
1520
it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);
1621
if (it == NULL)
1722
return NULL;
@@ -63,7 +68,7 @@ iter_iternext(PyObject *iterator)
6368
it = (seqiterobject *)iterator;
6469
seq = it->it_seq;
6570

66-
if (PyList_Check(seq)) {
71+
if (PyList_CheckExact(seq)) {
6772
PyObject *item;
6873
if (it->it_index >= PyList_GET_SIZE(seq)) {
6974
return NULL;
@@ -73,8 +78,19 @@ iter_iternext(PyObject *iterator)
7378
Py_INCREF(item);
7479
return item;
7580
}
81+
if (PyTuple_CheckExact(seq)) {
82+
PyObject *item;
83+
if (it->it_index >= PyTuple_GET_SIZE(seq)) {
84+
return NULL;
85+
}
86+
item = PyTuple_GET_ITEM(seq, it->it_index);
87+
it->it_index++;
88+
Py_INCREF(item);
89+
return item;
90+
}
7691
else {
77-
PyObject *result = PySequence_GetItem(seq, it->it_index++);
92+
PyObject *result = PySequence_ITEM(seq, it->it_index);
93+
it->it_index++;
7894
if (result != NULL) {
7995
return result;
8096
}

0 commit comments

Comments
 (0)