Index: Python/bltinmodule.c =================================================================== --- Python/bltinmodule.c (revision 80673) +++ Python/bltinmodule.c (working copy) @@ -974,11 +974,10 @@ curseq = PyTuple_GetItem(args, i+1); sqp->it = PyObject_GetIter(curseq); if (sqp->it == NULL) { - static char errmsg[] = - "argument %d to map() must support iteration"; - char errbuf[sizeof(errmsg) + 25]; - PyOS_snprintf(errbuf, sizeof(errbuf), errmsg, i+2); - PyErr_SetString(PyExc_TypeError, errbuf); + if (PyErr_ExceptionMatches(PyExc_TypeError)) + PyErr_Format(PyExc_TypeError, + "argument %d to map() must support iteration", + i+2); goto Fail_2; } @@ -1762,6 +1761,7 @@ int cmp_result; PyObject *zero = PyLong_FromLong(0); + PyObject *tmp; if (zero == NULL) return NULL; @@ -1782,43 +1782,50 @@ ilow = NULL; } assert(ihigh != NULL); - Py_INCREF(ihigh); /* ihigh correct now; do ilow */ - if (ilow == NULL) - ilow = zero; - Py_INCREF(ilow); - - /* ilow and ihigh correct now; do istep */ - if (istep == NULL) { - istep = PyLong_FromLong(1L); - if (istep == NULL) - goto Fail; + if (ilow == NULL) { + ilow = zero; + Py_INCREF(ilow); } - else { - Py_INCREF(istep); - } - - if (!PyInt_Check(ilow) && !PyLong_Check(ilow)) { + else if (PyInt_Check(ilow)) + Py_INCREF(ilow); + else if (PyFloat_Check(ilow) || !(tmp = PyNumber_Long(ilow))) { PyErr_Format(PyExc_TypeError, "range() integer start argument expected, got %s.", ilow->ob_type->tp_name); + ilow = ihigh = istep = NULL; goto Fail; - } + } else + ilow = tmp; - if (!PyInt_Check(ihigh) && !PyLong_Check(ihigh)) { + if (PyInt_Check(ihigh)) + Py_INCREF(ihigh); + else if (PyFloat_Check(ihigh) || !(tmp = PyNumber_Long(ihigh))) { PyErr_Format(PyExc_TypeError, "range() integer end argument expected, got %s.", ihigh->ob_type->tp_name); + ihigh = istep = NULL; goto Fail; + } else + ihigh = tmp; + + /* ilow and ihigh correct now; do istep */ + if (istep == NULL) { + istep = PyLong_FromLong(1L); + if (istep == NULL) + goto Fail; } - - if (!PyInt_Check(istep) && !PyLong_Check(istep)) { + else if (PyInt_Check(istep)) + Py_INCREF(istep); + else if (PyFloat_Check(istep) || !(tmp = PyNumber_Long(istep))) { PyErr_Format(PyExc_TypeError, "range() integer step argument expected, got %s.", istep->ob_type->tp_name); + istep = NULL; goto Fail; - } + } else + istep = tmp; if (PyObject_Cmp(istep, zero, &cmp_result) == -1) goto Fail; @@ -1869,14 +1876,14 @@ } Py_DECREF(ilow); Py_DECREF(ihigh); - Py_DECREF(istep); + Py_DECREF(istep); Py_DECREF(zero); Py_DECREF(curnum); return v; Fail: - Py_DECREF(ilow); - Py_DECREF(ihigh); + Py_XDECREF(ilow); + Py_XDECREF(ihigh); Py_XDECREF(istep); Py_DECREF(zero); Py_XDECREF(curnum); Index: Lib/test/test_builtin.py =================================================================== --- Lib/test/test_builtin.py (revision 80673) +++ Lib/test/test_builtin.py (working copy) @@ -1080,6 +1080,24 @@ self.assertRaises(OverflowError, range, -sys.maxint, sys.maxint) self.assertRaises(OverflowError, range, 0, 2*sys.maxint) + bignum = 2*sys.maxint + # Old-style user-defined class with __int__ method + class I0: + def __init__(self, n): + self.n = int(n) + def __int__(self): + return self.n + self.assertEqual(range(I0(bignum), I0(bignum + 1)), [bignum]) + if 0: + # New-style user-defined class with __int__ method + class I1(object): + def __init__(self, n): + self.n = int(n) + def __int__(self): + return self.n + self.assertEqual(range(I1(bignum), I1(bignum + 1)), [bignum]) + + def test_input_and_raw_input(self): self.write_testfile() fp = open(TESTFN, 'r')