diff options
author | Guido van Rossum <guido@python.org> | 1998-07-10 16:22:44 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1998-07-10 16:22:44 (GMT) |
commit | bfc725bf64c1da301fe29b9722efc56e34799cf4 (patch) | |
tree | fc4a2176935539cbb041d99e0b489afadada4d8b | |
parent | df901dfdea08e29730aff9872a051e05b0104dfe (diff) | |
download | cpython-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.c | 65 |
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; } |