Issue #4910 (1st patch of a series): fix int() and the corresponding

PyNumber_Int/PyNumber_Long API function so that it no longer attempts
to call the __long__ method for conversion.  Only the __int__ and __trunc__
methods are used.  (This removes a major remaining use of the nb_long
slot from the Python 3.x core.)

Thanks Benjamin for review.
This commit is contained in:
Mark Dickinson 2009-01-12 20:49:19 +00:00
parent 7c2b66cc02
commit e5e298f875
3 changed files with 23 additions and 17 deletions

View File

@ -367,7 +367,7 @@ def test_long(self):
def test_conversion(self):
# Test __long__()
# Test __int__()
class ClassicMissingMethods:
pass
self.assertRaises(TypeError, int, ClassicMissingMethods())
@ -410,18 +410,32 @@ def __int__(self):
class Classic:
pass
for base in (object, Classic):
class LongOverridesTrunc(base):
def __long__(self):
class IntOverridesTrunc(base):
def __int__(self):
return 42
def __trunc__(self):
return -12
self.assertEqual(int(LongOverridesTrunc()), 42)
self.assertEqual(int(IntOverridesTrunc()), 42)
class JustTrunc(base):
def __trunc__(self):
return 42
self.assertEqual(int(JustTrunc()), 42)
class JustLong(base):
# test that __long__ no longer used in 3.x
def __long__(self):
return 42
self.assertRaises(TypeError, int, JustLong())
class LongTrunc(base):
# __long__ should be ignored in 3.x
def __long__(self):
return 42
def __trunc__(self):
return 1729
self.assertEqual(int(LongTrunc()), 1729)
for trunc_result_base in (object, Classic):
class Integral(trunc_result_base):
def __int__(self):

View File

@ -12,6 +12,10 @@ What's New in Python 3.1 alpha 0
Core and Builtins
-----------------
- Issue #4910: Builtin int() function and PyNumber_Long/PyNumber_Int API
function no longer attempt to call the __long__ slot to convert an object
to an integer. Only the __int__ and __trunc__ slots are examined.
- Issue #4893: Use NT threading on CE.
- Issue #4915: Port sysmodule to Windows CE.

View File

@ -1379,19 +1379,7 @@ PyNumber_Long(PyObject *o)
}
return res;
}
if (m && m->nb_long) { /* This should include subclasses of long */
/* Classic classes always take this branch. */
PyObject *res = m->nb_long(o);
if (res && !PyLong_Check(res)) {
PyErr_Format(PyExc_TypeError,
"__long__ returned non-long (type %.200s)",
res->ob_type->tp_name);
Py_DECREF(res);
return NULL;
}
return res;
}
if (PyLong_Check(o)) /* A long subclass without nb_long */
if (PyLong_Check(o)) /* An int subclass without nb_int */
return _PyLong_Copy((PyLongObject *)o);
trunc_func = PyObject_GetAttr(o, trunc_name);
if (trunc_func) {