Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bfc725b

Browse files
committed
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.)
1 parent df901df commit bfc725b

1 file changed

Lines changed: 38 additions & 27 deletions

File tree

Objects/abstract.c

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,30 +1005,12 @@ PySequence_Tuple(v)
10051005
if (PyList_Check(v))
10061006
return PyList_AsTuple(v);
10071007

1008-
if (PyString_Check(v)) {
1009-
int n = PyString_Size(v);
1010-
PyObject *t = PyTuple_New(n);
1011-
if (t != NULL) {
1012-
int i;
1013-
char *p = PyString_AsString(v);
1014-
for (i = 0; i < n; i++) {
1015-
PyObject *item =
1016-
PyString_FromStringAndSize(p+i, 1);
1017-
if (item == NULL) {
1018-
Py_DECREF(t);
1019-
t = NULL;
1020-
break;
1021-
}
1022-
PyTuple_SetItem(t, i, item);
1023-
}
1024-
}
1025-
return t;
1026-
}
1008+
/* There used to be code for strings here, but tuplifying strings is
1009+
not a common activity, so I nuked it. Down with code bloat! */
10271010

10281011
/* Generic sequence object */
10291012
m = v->ob_type->tp_as_sequence;
10301013
if (m && m->sq_item) {
1031-
/* XXX Should support indefinite-length sequences */
10321014
int i;
10331015
PyObject *t;
10341016
int n = PySequence_Length(v);
@@ -1037,15 +1019,29 @@ PySequence_Tuple(v)
10371019
t = PyTuple_New(n);
10381020
if (t == NULL)
10391021
return NULL;
1040-
for (i = 0; i < n; i++) {
1022+
for (i = 0; ; i++) {
10411023
PyObject *item = (*m->sq_item)(v, i);
10421024
if (item == NULL) {
1043-
Py_DECREF(t);
1044-
t = NULL;
1025+
if (PyErr_ExceptionMatches(PyExc_IndexError))
1026+
PyErr_Clear();
1027+
else {
1028+
Py_DECREF(t);
1029+
t = NULL;
1030+
}
10451031
break;
10461032
}
1047-
PyTuple_SetItem(t, i, item);
1033+
if (i >= n) {
1034+
if (n < 500)
1035+
n += 10;
1036+
else
1037+
n += 100;
1038+
if (_PyTuple_Resize(&t, n, 0) != 0)
1039+
break;
1040+
}
1041+
PyTuple_SET_ITEM(t, i, item);
10481042
}
1043+
if (i < n && t != NULL)
1044+
_PyTuple_Resize(&t, i, 0);
10491045
return t;
10501046
}
10511047

@@ -1061,7 +1057,6 @@ PySequence_List(v)
10611057

10621058
m = v->ob_type->tp_as_sequence;
10631059
if (m && m->sq_item) {
1064-
/* XXX Should support indefinite-length sequences */
10651060
int i;
10661061
PyObject *l;
10671062
int n = PySequence_Length(v);
@@ -1070,14 +1065,30 @@ PySequence_List(v)
10701065
l = PyList_New(n);
10711066
if (l == NULL)
10721067
return NULL;
1073-
for (i = 0; i < n; i++) {
1068+
for (i = 0; ; i++) {
10741069
PyObject *item = (*m->sq_item)(v, i);
10751070
if (item == NULL) {
1071+
if (PyErr_ExceptionMatches(PyExc_IndexError))
1072+
PyErr_Clear();
1073+
else {
1074+
Py_DECREF(l);
1075+
l = NULL;
1076+
}
1077+
break;
1078+
}
1079+
if (i < n)
1080+
PyList_SET_ITEM(l, i, item);
1081+
else if (PyList_Append(l, item) < 0) {
10761082
Py_DECREF(l);
10771083
l = NULL;
10781084
break;
10791085
}
1080-
PyList_SetItem(l, i, item);
1086+
}
1087+
if (i < n && l != NULL) {
1088+
if (PyList_SetSlice(l, i, n, (PyObject *)NULL) != 0) {
1089+
Py_DECREF(l);
1090+
l = NULL;
1091+
}
10811092
}
10821093
return l;
10831094
}

0 commit comments

Comments
 (0)