mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +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))
|
if (PyList_Check(v))
|
||||||
return PyList_AsTuple(v);
|
return PyList_AsTuple(v);
|
||||||
|
|
||||||
if (PyString_Check(v)) {
|
/* There used to be code for strings here, but tuplifying strings is
|
||||||
int n = PyString_Size(v);
|
not a common activity, so I nuked it. Down with code bloat! */
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generic sequence object */
|
/* Generic sequence object */
|
||||||
m = v->ob_type->tp_as_sequence;
|
m = v->ob_type->tp_as_sequence;
|
||||||
if (m && m->sq_item) {
|
if (m && m->sq_item) {
|
||||||
/* XXX Should support indefinite-length sequences */
|
|
||||||
int i;
|
int i;
|
||||||
PyObject *t;
|
PyObject *t;
|
||||||
int n = PySequence_Length(v);
|
int n = PySequence_Length(v);
|
||||||
|
@ -1037,15 +1019,29 @@ PySequence_Tuple(v)
|
||||||
t = PyTuple_New(n);
|
t = PyTuple_New(n);
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; ; i++) {
|
||||||
PyObject *item = (*m->sq_item)(v, i);
|
PyObject *item = (*m->sq_item)(v, i);
|
||||||
if (item == NULL) {
|
if (item == NULL) {
|
||||||
|
if (PyErr_ExceptionMatches(PyExc_IndexError))
|
||||||
|
PyErr_Clear();
|
||||||
|
else {
|
||||||
Py_DECREF(t);
|
Py_DECREF(t);
|
||||||
t = NULL;
|
t = NULL;
|
||||||
|
}
|
||||||
break;
|
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;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1061,7 +1057,6 @@ PySequence_List(v)
|
||||||
|
|
||||||
m = v->ob_type->tp_as_sequence;
|
m = v->ob_type->tp_as_sequence;
|
||||||
if (m && m->sq_item) {
|
if (m && m->sq_item) {
|
||||||
/* XXX Should support indefinite-length sequences */
|
|
||||||
int i;
|
int i;
|
||||||
PyObject *l;
|
PyObject *l;
|
||||||
int n = PySequence_Length(v);
|
int n = PySequence_Length(v);
|
||||||
|
@ -1070,14 +1065,30 @@ PySequence_List(v)
|
||||||
l = PyList_New(n);
|
l = PyList_New(n);
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; ; i++) {
|
||||||
PyObject *item = (*m->sq_item)(v, i);
|
PyObject *item = (*m->sq_item)(v, i);
|
||||||
if (item == NULL) {
|
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);
|
Py_DECREF(l);
|
||||||
l = NULL;
|
l = NULL;
|
||||||
break;
|
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;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue