Eliminate a big block of duplicate code in PySequence_List() by

exposing _PyList_Extend().
This commit is contained in:
Raymond Hettinger 2004-03-11 09:13:12 +00:00
parent 97bc618229
commit 8ca92ae54c
3 changed files with 13 additions and 54 deletions

View File

@ -41,6 +41,7 @@ PyAPI_FUNC(int) PyList_SetSlice(PyObject *, int, int, PyObject *);
PyAPI_FUNC(int) PyList_Sort(PyObject *); PyAPI_FUNC(int) PyList_Sort(PyObject *);
PyAPI_FUNC(int) PyList_Reverse(PyObject *); PyAPI_FUNC(int) PyList_Reverse(PyObject *);
PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *); PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *);
PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *);
/* Macro, trading safety for speed */ /* Macro, trading safety for speed */
#define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i]) #define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i])

View File

@ -1427,69 +1427,21 @@ Fail:
PyObject * PyObject *
PySequence_List(PyObject *v) PySequence_List(PyObject *v)
{ {
PyObject *it; /* iter(v) */
PyObject *result; /* result list */ PyObject *result; /* result list */
int n; /* guess for result list size */ PyObject *rv; /* return value from PyList_Extend */
int i;
if (v == NULL) if (v == NULL)
return null_error(); return null_error();
/* Special-case list(a_list), for speed. */ result = PyList_New(0);
if (PyList_Check(v)) if (result == NULL)
return PyList_GetSlice(v, 0, PyList_GET_SIZE(v));
/* Get iterator. There may be some low-level efficiency to be gained
* by caching the tp_iternext slot instead of using PyIter_Next()
* later, but premature optimization is the root etc.
*/
it = PyObject_GetIter(v);
if (it == NULL)
return NULL; return NULL;
/* Guess a result list size. */ rv = _PyList_Extend((PyListObject *)result, v);
n = PyObject_Size(v); if (rv == NULL) {
if (n < 0) { Py_DECREF(result);
PyErr_Clear();
n = 8; /* arbitrary */
}
result = PyList_New(n);
if (result == NULL) {
Py_DECREF(it);
return NULL; return NULL;
} }
/* Run iterator to exhaustion. */
for (i = 0; ; i++) {
PyObject *item = PyIter_Next(it);
if (item == NULL) {
if (PyErr_Occurred()) {
Py_DECREF(result);
result = NULL;
}
break;
}
if (i < n)
PyList_SET_ITEM(result, i, item); /* steals ref */
else {
int status = PyList_Append(result, item);
Py_DECREF(item); /* append creates a new ref */
if (status < 0) {
Py_DECREF(result);
result = NULL;
break;
}
}
}
/* Cut back result list if initial guess was too large. */
if (i < n && result != NULL) {
if (PyList_SetSlice(result, i, n, (PyObject *)NULL) != 0) {
Py_DECREF(result);
result = NULL;
}
}
Py_DECREF(it);
return result; return result;
} }

View File

@ -776,6 +776,12 @@ listextend(PyListObject *self, PyObject *b)
return NULL; return NULL;
} }
PyObject *
_PyList_Extend(PyListObject *self, PyObject *b)
{
return listextend(self, b);
}
static PyObject * static PyObject *
list_inplace_concat(PyListObject *self, PyObject *other) list_inplace_concat(PyListObject *self, PyObject *other)
{ {