]> granicus.if.org Git - python/commitdiff
Issue #4910 (1st patch of a series): fix int() and the corresponding
authorMark Dickinson <dickinsm@gmail.com>
Mon, 12 Jan 2009 20:49:19 +0000 (20:49 +0000)
committerMark Dickinson <dickinsm@gmail.com>
Mon, 12 Jan 2009 20:49:19 +0000 (20:49 +0000)
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.

Lib/test/test_long.py
Misc/NEWS
Objects/abstract.c

index cbd0b2b46eefc1a36f4d6f882500f28bc60fa32b..ed8c886cb36066dd21ec73c93c37a59a2d417a19 100644 (file)
@@ -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):
index 461fe1d73141120a3ef5e175538c08a1c177f8a1..9e7afee83ca3c1ea00a615eb32caae92470f0b4d 100644 (file)
--- 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.
index aee20d69ade0948fd72ee4caa3da5ccd3c7de9cf..0a0333c73a16ef5c72b67dd147ca3aca540453f9 100644 (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) {