]> granicus.if.org Git - python/commitdiff
Patch #552433: Special-case tuples. Avoid sub-type checking for lists.
authorMartin v. Löwis <martin@v.loewis.de>
Wed, 8 May 2002 08:44:21 +0000 (08:44 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Wed, 8 May 2002 08:44:21 +0000 (08:44 +0000)
Avoid checks for negative indices and duplicate checks for support of
the sequence protocol.

Doc/api/abstract.tex
Include/abstract.h
Misc/NEWS
Objects/iterobject.c

index 0e25afa8d3fe9a43f144119c013647d02aa0d896..e4f299d0fbacb5c27d1bdaeb174a6b36cc6e0bbb 100644 (file)
@@ -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
index 226e5e8d0c0d861ff3f2d271e30b0747079afa33..459bd566d7690ac29ff92c7f559b6b916b00253a 100644 (file)
@@ -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);
 
        /*
index 34befe86aec21b9e7e23ee362ec7a981e94e879a..d31e09d8507bd74e12f347d3b1f38c192f0252b8 100644 (file)
--- 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.
index 789eb6c6890979a36454b6a2d19b806306eb3c40..de9f2f9e5d9f0074f6e49127175beb4a09a19c8e 100644 (file)
@@ -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;
                }