mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Changed PySequence_List() and PySequence_Tuple() to support
"indefinite length" sequences. These should still have a length, but the length is only used as a hint -- the actual length of the sequence is determined by the item that raises IndexError, which may be either smaller or larger than what len() returns. (This is a novelty; map(), filter() and reduce() only allow the actual length to be larger than what len() returns, not shorter. I'll fix that shortly.)
This commit is contained in:
parent
df901dfdea
commit
bfc725bf64
1 changed files with 38 additions and 27 deletions
|
@ -1005,30 +1005,12 @@ PySequence_Tuple(v)
|
|||
if (PyList_Check(v))
|
||||
return PyList_AsTuple(v);
|
||||
|
||||
if (PyString_Check(v)) {
|
||||
int n = PyString_Size(v);
|
||||
PyObject *t = PyTuple_New(n);
|
||||
if (t != NULL) {
|
||||
int i;
|
||||
char *p = PyString_AsString(v);
|
||||
for (i = 0; i < n; i++) {
|
||||
PyObject *item =
|
||||
PyString_FromStringAndSize(p+i, 1);
|
||||
if (item == NULL) {
|
||||
Py_DECREF(t);
|
||||
t = NULL;
|
||||
break;
|
||||
}
|
||||
PyTuple_SetItem(t, i, item);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
/* There used to be code for strings here, but tuplifying strings is
|
||||
not a common activity, so I nuked it. Down with code bloat! */
|
||||
|
||||
/* Generic sequence object */
|
||||
m = v->ob_type->tp_as_sequence;
|
||||
if (m && m->sq_item) {
|
||||
/* XXX Should support indefinite-length sequences */
|
||||
int i;
|
||||
PyObject *t;
|
||||
int n = PySequence_Length(v);
|
||||
|
@ -1037,15 +1019,29 @@ PySequence_Tuple(v)
|
|||
t = PyTuple_New(n);
|
||||
if (t == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < n; i++) {
|
||||
for (i = 0; ; i++) {
|
||||
PyObject *item = (*m->sq_item)(v, i);
|
||||
if (item == NULL) {
|
||||
Py_DECREF(t);
|
||||
t = NULL;
|
||||
if (PyErr_ExceptionMatches(PyExc_IndexError))
|
||||
PyErr_Clear();
|
||||
else {
|
||||
Py_DECREF(t);
|
||||
t = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
PyTuple_SetItem(t, i, item);
|
||||
if (i >= n) {
|
||||
if (n < 500)
|
||||
n += 10;
|
||||
else
|
||||
n += 100;
|
||||
if (_PyTuple_Resize(&t, n, 0) != 0)
|
||||
break;
|
||||
}
|
||||
PyTuple_SET_ITEM(t, i, item);
|
||||
}
|
||||
if (i < n && t != NULL)
|
||||
_PyTuple_Resize(&t, i, 0);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -1061,7 +1057,6 @@ PySequence_List(v)
|
|||
|
||||
m = v->ob_type->tp_as_sequence;
|
||||
if (m && m->sq_item) {
|
||||
/* XXX Should support indefinite-length sequences */
|
||||
int i;
|
||||
PyObject *l;
|
||||
int n = PySequence_Length(v);
|
||||
|
@ -1070,14 +1065,30 @@ PySequence_List(v)
|
|||
l = PyList_New(n);
|
||||
if (l == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < n; i++) {
|
||||
for (i = 0; ; i++) {
|
||||
PyObject *item = (*m->sq_item)(v, i);
|
||||
if (item == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_IndexError))
|
||||
PyErr_Clear();
|
||||
else {
|
||||
Py_DECREF(l);
|
||||
l = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (i < n)
|
||||
PyList_SET_ITEM(l, i, item);
|
||||
else if (PyList_Append(l, item) < 0) {
|
||||
Py_DECREF(l);
|
||||
l = NULL;
|
||||
break;
|
||||
}
|
||||
PyList_SetItem(l, i, item);
|
||||
}
|
||||
if (i < n && l != NULL) {
|
||||
if (PyList_SetSlice(l, i, n, (PyObject *)NULL) != 0) {
|
||||
Py_DECREF(l);
|
||||
l = NULL;
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue