summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1998-07-10 16:22:44 (GMT)
committerGuido van Rossum <guido@python.org>1998-07-10 16:22:44 (GMT)
commitbfc725bf64c1da301fe29b9722efc56e34799cf4 (patch)
treefc4a2176935539cbb041d99e0b489afadada4d8b
parentdf901dfdea08e29730aff9872a051e05b0104dfe (diff)
downloadcpython-bfc725bf64c1da301fe29b9722efc56e34799cf4.zip
cpython-bfc725bf64c1da301fe29b9722efc56e34799cf4.tar.gz
cpython-bfc725bf64c1da301fe29b9722efc56e34799cf4.tar.bz2
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.)
-rw-r--r--Objects/abstract.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 086987e..a94a136 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -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;
}