diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-04-28 08:20:22 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-04-28 08:20:22 (GMT) |
commit | 748b8bbe020561cdb953b052f7f9d43be83d8081 (patch) | |
tree | 782b257eef3368631c4bcddeee83a682308952cc | |
parent | b3d8d1f76c64998e7e7789955718c1c24b2f84c6 (diff) | |
download | cpython-748b8bbe020561cdb953b052f7f9d43be83d8081.zip cpython-748b8bbe020561cdb953b052f7f9d43be83d8081.tar.gz cpython-748b8bbe020561cdb953b052f7f9d43be83d8081.tar.bz2 |
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).
-rw-r--r-- | Python/bltinmodule.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 7e8f555..8572cc8 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -816,10 +816,10 @@ builtin_execfile(PyObject *self, PyObject *args) if (PyEval_GetNestedScopes()) { PyCompilerFlags cf; 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); - } else - res = PyRun_FileEx(fp, filename, Py_file_input, globals, + } else + res = PyRun_FileEx(fp, filename, Py_file_input, globals, locals, 1); return res; } @@ -924,7 +924,7 @@ builtin_map(PyObject *self, PyObject *args) typedef struct { PyObject *seq; PySequenceMethods *sqf; - int len; + int saw_IndexError; } sequence; PyObject *func, *result; @@ -952,6 +952,10 @@ builtin_map(PyObject *self, PyObject *args) 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) { int curlen; PySequenceMethods *sqf; @@ -959,9 +963,10 @@ builtin_map(PyObject *self, PyObject *args) if ((sqp->seq = PyTuple_GetItem(args, i + 1)) == NULL) goto Fail_2; + sqp->saw_IndexError = 0; + sqp->sqf = sqf = sqp->seq->ob_type->tp_as_sequence; if (sqf == NULL || - sqf->sq_length == NULL || sqf->sq_item == NULL) { static char errmsg[] = @@ -973,9 +978,13 @@ builtin_map(PyObject *self, PyObject *args) 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; - if (curlen > len) len = curlen; } @@ -983,6 +992,7 @@ builtin_map(PyObject *self, PyObject *args) if ((result = (PyObject *) PyList_New(len)) == NULL) goto Fail_2; + /* Iterate over the sequences until all have raised IndexError. */ for (i = 0; ; ++i) { PyObject *alist, *item=NULL, *value; int any = 0; @@ -995,7 +1005,7 @@ builtin_map(PyObject *self, PyObject *args) } for (j = 0, sqp = seqs; j < n; ++j, ++sqp) { - if (sqp->len < 0) { + if (sqp->saw_IndexError) { Py_INCREF(Py_None); item = Py_None; } @@ -1008,7 +1018,7 @@ builtin_map(PyObject *self, PyObject *args) PyErr_Clear(); Py_INCREF(Py_None); item = Py_None; - sqp->len = -1; + sqp->saw_IndexError = 1; } else { goto Fail_0; |