New submission from Lukas Lueg <[email protected]>:
The built-in function map() currently swallows any exception that might have
occured while trying to get an iterator from any parameter. This produces
unexpected behaviour for applications that require a certain type of exception
to be raised when __iter__() is called on their objects.
>From 24179f82b7de, inside map_new():
973 /* Get iterator. */
974 curseq = PyTuple_GetItem(args, i+1);
975 sqp->it = PyObject_GetIter(curseq);
976 if (sqp->it == NULL) {
977 static char errmsg[] =
978 "argument %d to map() must support iteration";
979 char errbuf[sizeof(errmsg) + 25];
980 PyOS_snprintf(errbuf, sizeof(errbuf), errmsg, i+2);
981 PyErr_SetString(PyExc_TypeError, errbuf);
982 goto Fail_2;
983 }
We *must* check if there has been any other kind of exception already being set
when returning from PyObject_GetIter before setting PyExc_TypeError in line
981. If there is none, it is ok to raise a TypeError; any other exception must
be passed on.
For example: raising TooManyCacheMissesException in __iter__() causes
map(foobar, myobject) to raise TypeError instead of TooManyCacheMissesException.
Workaround: use map(foobar, iter(myobject)). The explicit call to iter will
either produce an iterator object (which returns self to map()) or raises the
correct exception.
Python 3 is not affected as map_new() does not throw it's own TypeError in case
PyObject_GetIter() fails.
----------
components: None
messages: 131932
nosy: ebfe
priority: normal
severity: normal
status: open
title: map() must not swallow exceptions from PyObject_GetIter
versions: Python 2.7
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue11655>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com