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): def test_conversion(self):
# Test __long__() # Test __int__()
class ClassicMissingMethods: class ClassicMissingMethods:
pass pass
self.assertRaises(TypeError, int, ClassicMissingMethods()) self.assertRaises(TypeError, int, ClassicMissingMethods())
@ -410,18 +410,32 @@ def __int__(self):
class Classic: class Classic:
pass pass
for base in (object, Classic): for base in (object, Classic):
class LongOverridesTrunc(base): class IntOverridesTrunc(base):
def __long__(self): def __int__(self):
return 42 return 42
def __trunc__(self): def __trunc__(self):
return -12 return -12
self.assertEqual(int(LongOverridesTrunc()), 42) self.assertEqual(int(IntOverridesTrunc()), 42)
class JustTrunc(base): class JustTrunc(base):
def __trunc__(self): def __trunc__(self):
return 42 return 42
self.assertEqual(int(JustTrunc()), 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): for trunc_result_base in (object, Classic):
class Integral(trunc_result_base): class Integral(trunc_result_base):
def __int__(self): def __int__(self):

View File

@ -12,6 +12,10 @@ What's New in Python 3.1 alpha 0
Core and Builtins 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 #4893: Use NT threading on CE.
- Issue #4915: Port sysmodule to Windows CE. - Issue #4915: Port sysmodule to Windows CE.

View File

@ -1379,19 +1379,7 @@ PyNumber_Long(PyObject *o)
} }
return res; return res;
} }
if (m && m->nb_long) { /* This should include subclasses of long */ if (PyLong_Check(o)) /* An int subclass without nb_int */
/* 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 */
return _PyLong_Copy((PyLongObject *)o); return _PyLong_Copy((PyLongObject *)o);
trunc_func = PyObject_GetAttr(o, trunc_name); trunc_func = PyObject_GetAttr(o, trunc_name);
if (trunc_func) { if (trunc_func) {