From: Thomas Heller Date: Thu, 24 Jan 2008 13:08:54 +0000 (+0000) Subject: Invert the checks in get_[u]long and get_[u]longlong. The intent was X-Git-Tag: v2.5.2c1~53 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fe528ebf6829b9be7cce38c7b15a3815a361faa2;p=python Invert the checks in get_[u]long and get_[u]longlong. The intent was to not accept float types; the result was that integer-like objects were not accepted. --- diff --git a/Lib/ctypes/test/test_numbers.py b/Lib/ctypes/test/test_numbers.py index c22688dba9..c098be1b8b 100644 --- a/Lib/ctypes/test/test_numbers.py +++ b/Lib/ctypes/test/test_numbers.py @@ -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: diff --git a/Misc/NEWS b/Misc/NEWS index eb23c0971e..46d3f665a0 100644 --- 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. diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 0fd82bc02f..d310ac5482 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -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;