diff --git a/Doc/api/abstract.tex b/Doc/api/abstract.tex index f19928f9fc2..b38bc91064c 100644 --- a/Doc/api/abstract.tex +++ b/Doc/api/abstract.tex @@ -830,6 +830,13 @@ determination. and that \var{i} is within bounds. \end{cfuncdesc} +\begin{cfuncdesc}{PyObject**}{PySequence_Fast_ITEMS}{PyObject *o} + Return the underlying array of PyObject pointers. Assumes that + \var{o} was returned by \cfunction{PySequence_Fast()} and + \var{o} is not \NULL. + \versionadded{2.4} +\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 diff --git a/Include/abstract.h b/Include/abstract.h index 46aee297d00..bc9df05d84d 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -1016,6 +1016,12 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ need to be corrected for a negative index */ +#define _PySequence_Fast_ITEMS(sf) \ + (PyList_Check(sf) ? ((PyListObject *)(sf))->ob_item \ + : ((PyTupleObject *)(sf))->ob_item) + /* Return a pointer to the underlying item array for + an object retured by PySequence_Fast */ + PyAPI_FUNC(int) PySequence_Count(PyObject *o, PyObject *value); /* diff --git a/Misc/NEWS b/Misc/NEWS index 21114d4e4cd..9c5d80ac596 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -412,6 +412,9 @@ Build C API ----- +- Added a new macro, PySequence_Fast_ITEMS, which retrieves a fast sequence's + underlying array of PyObject pointers. Useful for high speed looping. + - Created a new method flag, METH_COEXIST, which causes a method to be loaded even if already defined by a slot wrapper. This allows a __contains__ method, for example, to co-exist with a defined sq_contains slot. This diff --git a/Objects/listobject.c b/Objects/listobject.c index 2f2097d0d5a..78def29bd1b 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -491,12 +491,7 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v) if(v_as_SF == NULL) return -1; n = PySequence_Fast_GET_SIZE(v_as_SF); - if (PyList_Check(v_as_SF)) - vitem = ((PyListObject *)v_as_SF)->ob_item; - else { - assert (PyTuple_Check(v_as_SF)); - vitem = ((PyTupleObject *)v_as_SF)->ob_item; - } + vitem = _PySequence_Fast_ITEMS(v_as_SF); } if (ilow < 0) ilow = 0; @@ -691,12 +686,7 @@ listextend_internal(PyListObject *self, PyObject *b) } /* populate the end of self with b's items */ - if (PyList_Check(b)) - src = ((PyListObject *)b)->ob_item; - else { - assert (PyTuple_Check(b)); - src = ((PyTupleObject *)b)->ob_item; - } + src = _PySequence_Fast_ITEMS(b); dest = self->ob_item + selflen; for (i = 0; i < blen; i++) { PyObject *o = src[i]; @@ -2571,10 +2561,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) PyMem_MALLOC(slicelength*sizeof(PyObject*)); selfitems = self->ob_item; - if (PyList_Check(seq)) - seqitems = ((PyListObject *)seq)->ob_item; - else - seqitems = ((PyTupleObject *)seq)->ob_item; + seqitems = _PySequence_Fast_ITEMS(seq); for (cur = start, i = 0; i < slicelength; cur += step, i++) { garbage[i] = selfitems[cur];