]> granicus.if.org Git - python/commitdiff
Invert the checks in get_[u]long and get_[u]longlong. The intent was
authorThomas Heller <theller@ctypes.org>
Thu, 24 Jan 2008 13:08:54 +0000 (13:08 +0000)
committerThomas Heller <theller@ctypes.org>
Thu, 24 Jan 2008 13:08:54 +0000 (13:08 +0000)
to not accept float types; the result was that integer-like objects
were not accepted.

Lib/ctypes/test/test_numbers.py
Misc/NEWS
Modules/_ctypes/cfield.c

index c22688dba9b32a4dbd94f3c899f3fb01895fde04..c098be1b8b5ab6b2f0d44486ff6c391687f528f8 100644 (file)
@@ -90,15 +90,31 @@ class NumberTestCase(unittest.TestCase):
     def test_floats(self):
         # c_float and c_double can be created from
         # Python int, long and float
+        class FloatLike(object):
+            def __float__(self):
+                return 2.0
+        f = FloatLike()
         for t in float_types:
             self.failUnlessEqual(t(2.0).value, 2.0)
             self.failUnlessEqual(t(2).value, 2.0)
             self.failUnlessEqual(t(2L).value, 2.0)
+            self.failUnlessEqual(t(f).value, 2.0)
 
     def test_integers(self):
-        # integers cannot be constructed from floats
+        class FloatLike(object):
+            def __float__(self):
+                return 2.0
+        f = FloatLike()
+        class IntLike(object):
+            def __int__(self):
+                return 2
+        i = IntLike()
+        # integers cannot be constructed from floats,
+        # but from integer-like objects
         for t in signed_types + unsigned_types:
             self.assertRaises(TypeError, t, 3.14)
+            self.assertRaises(TypeError, t, f)
+            self.failUnlessEqual(t(i).value, 2)
 
     def test_sizes(self):
         for t in signed_types + unsigned_types + float_types:
index eb23c0971ed7e2f7c944ca5b73d9cee64d469d46..46d3f665a088485de1f937fcb69973bb8a0b9b49 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -67,6 +67,9 @@ Core and builtins
 Library
 -------
 
+- The ctypes int types did not accept objects implementing
+  __int__() in the constructor.
+
 - #1189216: Fix the zipfile module to work on archives with headers
   past the 2**31 byte boundary.
 
index 0fd82bc02fbbc7bf809509a0a1a73cc951b855df..d310ac54828ce13bf2f109ba59693c9b91bca591 100644 (file)
@@ -355,10 +355,9 @@ static int
 get_long(PyObject *v, long *p)
 {
        long x;
-       if (!PyInt_Check(v) && !PyLong_Check(v)) {
-               PyErr_Format(PyExc_TypeError,
-                            "int expected instead of %s instance",
-                            v->ob_type->tp_name);
+       if (PyFloat_Check(v)) {
+               PyErr_SetString(PyExc_TypeError,
+                               "int expected instead of float");
                return -1;
        }
        x = PyInt_AsUnsignedLongMask(v);
@@ -374,10 +373,9 @@ static int
 get_ulong(PyObject *v, unsigned long *p)
 {
        unsigned long x;
-       if (!PyInt_Check(v) && !PyLong_Check(v)) {
-               PyErr_Format(PyExc_TypeError,
-                            "int expected instead of %s instance",
-                            v->ob_type->tp_name);
+       if (PyFloat_Check(v)) {
+               PyErr_SetString(PyExc_TypeError,
+                               "int expected instead of float");
                return -1;
        }
        x = PyInt_AsUnsignedLongMask(v);
@@ -395,11 +393,10 @@ static int
 get_longlong(PyObject *v, PY_LONG_LONG *p)
 {
        PY_LONG_LONG x;
-       if (!PyInt_Check(v) && !PyLong_Check(v)) {
-               PyErr_Format(PyExc_TypeError,
-                            "int expected instead of %s instance",
-                            v->ob_type->tp_name);
-               return -1;
+       if (PyFloat_Check(v)) {
+               PyErr_SetString(PyExc_TypeError,
+                               "int expected instead of float");
+               return -1;
        }
        x = PyInt_AsUnsignedLongLongMask(v);
        if (x == -1 && PyErr_Occurred())
@@ -414,12 +411,11 @@ static int
 get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
 {
        unsigned PY_LONG_LONG x;
-       if (!PyInt_Check(v) && !PyLong_Check(v)) {
-               PyErr_Format(PyExc_TypeError,
-                            "int expected instead of %s instance",
-                            v->ob_type->tp_name);
-               return -1;
-       }
+       if (PyFloat_Check(v)) {
+               PyErr_SetString(PyExc_TypeError,
+                               "int expected instead of float");
+               return -1;
+       }
        x = PyInt_AsUnsignedLongLongMask(v);
        if (x == -1 && PyErr_Occurred())
                return -1;