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_Reverse(PyObject *);
PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *);
PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *);
/* Macro, trading safety for speed */
#define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i])

View File

@ -1427,69 +1427,21 @@ Fail:
PyObject *
PySequence_List(PyObject *v)
{
PyObject *it; /* iter(v) */
PyObject *result; /* result list */
int n; /* guess for result list size */
int i;
PyObject *rv; /* return value from PyList_Extend */
if (v == NULL)
return null_error();
/* Special-case list(a_list), for speed. */
if (PyList_Check(v))
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)
result = PyList_New(0);
if (result == NULL)
return NULL;
/* Guess a result list size. */
n = PyObject_Size(v);
if (n < 0) {
PyErr_Clear();
n = 8; /* arbitrary */
}
result = PyList_New(n);
if (result == NULL) {
Py_DECREF(it);
rv = _PyList_Extend((PyListObject *)result, v);
if (rv == NULL) {
Py_DECREF(result);
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;
}

View File

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