mirror of
https://github.com/python/cpython.git
synced 2025-10-17 12:18:23 +00:00
Fix buglet reported on c.l.py: map(fnc, file.xreadlines()) blows up.
Also a 2.1 bugfix candidate (am I supposed to do something with those?). Took away map()'s insistence that sequences support __len__, and cleaned up the convoluted code that made it *look* like it really cared about __len__ (in fact the old ->len field was only *used* as a flag bit, as the main loop only looked at its sign bit, setting the field to -1 when IndexError got raised; renamed the field to ->saw_IndexError instead).
This commit is contained in:
parent
b3d8d1f76c
commit
748b8bbe02
1 changed files with 19 additions and 9 deletions
|
@ -816,10 +816,10 @@ builtin_execfile(PyObject *self, PyObject *args)
|
||||||
if (PyEval_GetNestedScopes()) {
|
if (PyEval_GetNestedScopes()) {
|
||||||
PyCompilerFlags cf;
|
PyCompilerFlags cf;
|
||||||
cf.cf_nested_scopes = 1;
|
cf.cf_nested_scopes = 1;
|
||||||
res = PyRun_FileExFlags(fp, filename, Py_file_input, globals,
|
res = PyRun_FileExFlags(fp, filename, Py_file_input, globals,
|
||||||
locals, 1, &cf);
|
locals, 1, &cf);
|
||||||
} else
|
} else
|
||||||
res = PyRun_FileEx(fp, filename, Py_file_input, globals,
|
res = PyRun_FileEx(fp, filename, Py_file_input, globals,
|
||||||
locals, 1);
|
locals, 1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -924,7 +924,7 @@ builtin_map(PyObject *self, PyObject *args)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject *seq;
|
PyObject *seq;
|
||||||
PySequenceMethods *sqf;
|
PySequenceMethods *sqf;
|
||||||
int len;
|
int saw_IndexError;
|
||||||
} sequence;
|
} sequence;
|
||||||
|
|
||||||
PyObject *func, *result;
|
PyObject *func, *result;
|
||||||
|
@ -952,6 +952,10 @@ builtin_map(PyObject *self, PyObject *args)
|
||||||
goto Fail_2;
|
goto Fail_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do a first pass to (a) verify the args are sequences; (b) set
|
||||||
|
* len to the largest of their lengths; (c) initialize the seqs
|
||||||
|
* descriptor vector.
|
||||||
|
*/
|
||||||
for (len = 0, i = 0, sqp = seqs; i < n; ++i, ++sqp) {
|
for (len = 0, i = 0, sqp = seqs; i < n; ++i, ++sqp) {
|
||||||
int curlen;
|
int curlen;
|
||||||
PySequenceMethods *sqf;
|
PySequenceMethods *sqf;
|
||||||
|
@ -959,9 +963,10 @@ builtin_map(PyObject *self, PyObject *args)
|
||||||
if ((sqp->seq = PyTuple_GetItem(args, i + 1)) == NULL)
|
if ((sqp->seq = PyTuple_GetItem(args, i + 1)) == NULL)
|
||||||
goto Fail_2;
|
goto Fail_2;
|
||||||
|
|
||||||
|
sqp->saw_IndexError = 0;
|
||||||
|
|
||||||
sqp->sqf = sqf = sqp->seq->ob_type->tp_as_sequence;
|
sqp->sqf = sqf = sqp->seq->ob_type->tp_as_sequence;
|
||||||
if (sqf == NULL ||
|
if (sqf == NULL ||
|
||||||
sqf->sq_length == NULL ||
|
|
||||||
sqf->sq_item == NULL)
|
sqf->sq_item == NULL)
|
||||||
{
|
{
|
||||||
static char errmsg[] =
|
static char errmsg[] =
|
||||||
|
@ -973,9 +978,13 @@ builtin_map(PyObject *self, PyObject *args)
|
||||||
goto Fail_2;
|
goto Fail_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((curlen = sqp->len = (*sqp->sqf->sq_length)(sqp->seq)) < 0)
|
if (sqf->sq_length == NULL)
|
||||||
|
/* doesn't matter -- make something up */
|
||||||
|
curlen = 8;
|
||||||
|
else
|
||||||
|
curlen = (*sqf->sq_length)(sqp->seq);
|
||||||
|
if (curlen < 0)
|
||||||
goto Fail_2;
|
goto Fail_2;
|
||||||
|
|
||||||
if (curlen > len)
|
if (curlen > len)
|
||||||
len = curlen;
|
len = curlen;
|
||||||
}
|
}
|
||||||
|
@ -983,6 +992,7 @@ builtin_map(PyObject *self, PyObject *args)
|
||||||
if ((result = (PyObject *) PyList_New(len)) == NULL)
|
if ((result = (PyObject *) PyList_New(len)) == NULL)
|
||||||
goto Fail_2;
|
goto Fail_2;
|
||||||
|
|
||||||
|
/* Iterate over the sequences until all have raised IndexError. */
|
||||||
for (i = 0; ; ++i) {
|
for (i = 0; ; ++i) {
|
||||||
PyObject *alist, *item=NULL, *value;
|
PyObject *alist, *item=NULL, *value;
|
||||||
int any = 0;
|
int any = 0;
|
||||||
|
@ -995,7 +1005,7 @@ builtin_map(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0, sqp = seqs; j < n; ++j, ++sqp) {
|
for (j = 0, sqp = seqs; j < n; ++j, ++sqp) {
|
||||||
if (sqp->len < 0) {
|
if (sqp->saw_IndexError) {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
item = Py_None;
|
item = Py_None;
|
||||||
}
|
}
|
||||||
|
@ -1008,7 +1018,7 @@ builtin_map(PyObject *self, PyObject *args)
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
item = Py_None;
|
item = Py_None;
|
||||||
sqp->len = -1;
|
sqp->saw_IndexError = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
goto Fail_0;
|
goto Fail_0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue