summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2009-01-12 20:49:19 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2009-01-12 20:49:19 (GMT)
commite5e298f8755c475e78f8cfc71ee0ea03c6674406 (patch)
treee5d854149357c5207ce32822ff2dee49542eef41
parent7c2b66cc02a1c5e3433885640b7d4bd9e0ca5b8a (diff)
downloadcpython-e5e298f8755c475e78f8cfc71ee0ea03c6674406.zip
cpython-e5e298f8755c475e78f8cfc71ee0ea03c6674406.tar.gz
cpython-e5e298f8755c475e78f8cfc71ee0ea03c6674406.tar.bz2
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.
-rw-r--r--Lib/test/test_long.py22
-rw-r--r--Misc/NEWS4
-rw-r--r--Objects/abstract.c14
3 files changed, 23 insertions, 17 deletions
diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py
index cbd0b2b..ed8c886 100644
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -367,7 +367,7 @@ class LongTest(unittest.TestCase):
def test_conversion(self):
- # Test __long__()
+ # Test __int__()
class ClassicMissingMethods:
pass
self.assertRaises(TypeError, int, ClassicMissingMethods())
@@ -410,18 +410,32 @@ class LongTest(unittest.TestCase):
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):
diff --git a/Misc/NEWS b/Misc/NEWS
index 461fe1d..9e7afee 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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.
diff --git a/Objects/abstract.c b/Objects/abstract.c
index aee20d6..0a0333c 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -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) {