diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index fc61d21..360e48e 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -507,8 +507,8 @@ class ClassTests(unittest.TestCase): callLst[:] = [] as_int = int(mixIntAndLong) - self.assertEquals(type(as_int), long) - self.assertEquals(as_int, 42L) + self.assertEquals(type(as_int), int) + self.assertEquals(as_int, 42) self.assertCallStack([('__int__', (mixIntAndLong,))]) callLst[:] = [] diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index 514a98e..e68cf42 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -393,6 +393,36 @@ class IntTestCases(unittest.TestCase): self.fail("Failed to raise TypeError with %s" % ((base, trunc_result_base),)) + def test_type(self): + maxint = sys.maxint + minint = -maxint - 1 + + class Integer: + def __init__(self, value): + self.value = value + def __int__(self): + return long(self.value) + def test_int(value): + return type(int(Integer(value))) + + self.assertEquals(test_int(maxint), int) + self.assertEquals(test_int(maxint + 1), long) + self.assertEquals(test_int(minint), int) + self.assertEquals(test_int(minint - 1), long) + + class Trunc: + def __init__(self, value): + self.value = value + def __trunc__(self): + return long(self.value) + def test_trunc(value): + return type(int(Trunc(value))) + + self.assertEquals(test_trunc(maxint), int) + self.assertEquals(test_trunc(maxint + 1), long) + self.assertEquals(test_trunc(minint), int) + self.assertEquals(test_trunc(minint - 1), long) + def test_main(): run_unittest(IntTestCases) diff --git a/Objects/abstract.c b/Objects/abstract.c index 5eb7b28..781918c 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1557,14 +1557,28 @@ _PyNumber_ConvertIntegralToInt(PyObject *integral, const char* error_format) { const char *type_name; static PyObject *int_name = NULL; + if (integral == NULL) + return NULL; + if (int_name == NULL) { int_name = PyString_InternFromString("__int__"); if (int_name == NULL) return NULL; } - if (integral && (!PyInt_Check(integral) && - !PyLong_Check(integral))) { + if (PyInt_Check(integral)) { + return integral; + } else if (PyLong_Check(integral)) { + long value; + value = PyLong_AsLong(integral); + if (value != -1 || !PyErr_Occurred()) { + Py_DECREF(integral); + integral = PyInt_FromLong(value); + } else { + PyErr_Clear(); + } + return integral; + } else { /* Don't go through tp_as_number->nb_int to avoid hitting the classic class fallback to __trunc__. */ PyObject *int_func = PyObject_GetAttr(integral, int_name); @@ -1621,7 +1635,18 @@ PyNumber_Int(PyObject *o) if (m && m->nb_int) { /* This should include subclasses of int */ /* Classic classes always take this branch. */ PyObject *res = m->nb_int(o); - if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { + if (res == NULL) + return NULL; + if (PyLong_Check(res)) { + long value; + value = PyLong_AsLong(res); + if (value != -1 || !PyErr_Occurred()) { + Py_DECREF(res); + res = PyInt_FromLong(value); + } else { + PyErr_Clear(); + } + } else if (!PyInt_Check(res)) { PyErr_Format(PyExc_TypeError, "__int__ returned non-int (type %.200s)", res->ob_type->tp_name);