From 5ca924038dd196217cedd4b02480ea16acd634f3 Mon Sep 17 00:00:00 2001 From: Thomas Heller Date: Thu, 24 Jan 2008 19:15:02 +0000 Subject: 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. Ported from release25-maint. --- Lib/ctypes/test/test_numbers.py | 18 +++++++++++++++++- Modules/_ctypes/cfield.c | 34 +++++++++++++++------------------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/Lib/ctypes/test/test_numbers.py b/Lib/ctypes/test/test_numbers.py index ff2da86..5845741 100644 --- a/Lib/ctypes/test/test_numbers.py +++ b/Lib/ctypes/test/test_numbers.py @@ -105,15 +105,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 + bool_types: diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 03aacbd..155e75e 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -346,10 +346,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); @@ -365,10 +364,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); @@ -386,11 +384,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()) @@ -405,12 +402,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; -- cgit v0.12