Index: Objects/typeobject.c =================================================================== --- Objects/typeobject.c (revision 66056) +++ Objects/typeobject.c (working copy) @@ -4630,11 +4630,18 @@ static PyObject *len_str; PyObject *res = call_method(self, "__len__", &len_str, "()"); Py_ssize_t len; + PyObject *err; if (res == NULL) return -1; - len = PyLong_AsSsize_t(res); + len = PyNumber_AsSsize_t(res, NULL); Py_DECREF(res); + if ((err = PyErr_Occurred()) && + PyErr_GivenExceptionMatches(err, PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "__len__() should return an int"); + return -1; + } if (len < 0) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_ValueError, Index: Lib/test/test_builtin.py =================================================================== --- Lib/test/test_builtin.py (revision 66056) +++ Lib/test/test_builtin.py (working copy) @@ -623,6 +623,10 @@ def __len__(self): raise ValueError self.assertRaises(ValueError, len, BadSeq()) + class WrongReturnType: + def __len__(self): + return .5 + self.assertRaises(TypeError, len, WrongReturnType()) def test_map(self): self.assertEqual(