Kaydet (Commit) 01f94bda authored tarafından Martin v. Löwis's avatar Martin v. Löwis

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.
üst 000e37c3
...@@ -765,6 +765,13 @@ determination. ...@@ -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
......
...@@ -1015,6 +1015,12 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ ...@@ -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);
/* /*
......
...@@ -192,6 +192,10 @@ Build ...@@ -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.
......
...@@ -12,6 +12,11 @@ PyObject * ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment