# HG changeset patch # User Mike Miller # Date 1470698241 25200 # Node ID a133564f4af7f5185e17b9bb61676bd3d6b7e988 # Parent 0d94e42bacf6ec353ce881b844c369e37ce82552 Convert integer types to appropriate Python int or long types (fixes issue #55) * octave_to_python.cc (pytave::python_integer_value): New functions to construct appropriate Python int or long types based on integer size and Python version. (pytave::octscalar_to_pyobject): Use them. * pycall.cc: Add %!tests for conversion of integer types into Python. diff -r 0d94e42bacf6 -r a133564f4af7 octave_to_python.cc --- a/octave_to_python.cc Tue Aug 02 13:53:12 2016 -0700 +++ b/octave_to_python.cc Mon Aug 08 16:17:21 2016 -0700 @@ -229,6 +229,42 @@ } } + inline PyObject * + python_integer_value (int32_t value) + { +#if PY_VERSION_HEX >= 0x03000000 + return PyLong_FromLong (value); +#else + return PyInt_FromLong (value); +#endif + } + + inline PyObject * + python_integer_value (uint32_t value) + { + return PyLong_FromUnsignedLong (value); + } + + inline PyObject * + python_integer_value (int64_t value) + { +#if (defined (HAVE_LONG_LONG) && (SIZEOF_LONG_LONG > SIZEOF_LONG)) + return PyLong_FromLongLong (value); +#else + return PyLong_FromLong (value); +#endif + } + + inline PyObject * + python_integer_value (uint64_t value) + { +#if (defined (HAVE_LONG_LONG) && (SIZEOF_LONG_LONG > SIZEOF_LONG)) + return PyLong_FromUnsignedLongLong (value); +#else + return PyLong_FromUnsignedLong (value); +#endif + } + static void octscalar_to_pyobject (boost::python::object& py_object, const octave_value& arg) @@ -242,22 +278,22 @@ obj = PyFloat_FromDouble (arg.double_value ()); else if (arg.is_int8_type ()) - obj = PyLong_FromLong (arg.int8_scalar_value ().value ()); + obj = python_integer_value (arg.int8_scalar_value ().value ()); else if (arg.is_int16_type ()) - obj = PyLong_FromLong (arg.int16_scalar_value ().value ()); + obj = python_integer_value (arg.int16_scalar_value ().value ()); else if (arg.is_int32_type ()) - obj = PyLong_FromLong (arg.int32_scalar_value ().value ()); + obj = python_integer_value (arg.int32_scalar_value ().value ()); else if (arg.is_int64_type ()) - obj = PyLong_FromLong (arg.int64_scalar_value ().value ()); + obj = python_integer_value (arg.int64_scalar_value ().value ()); else if (arg.is_uint8_type ()) - obj = PyLong_FromUnsignedLong (arg.uint8_scalar_value ().value ()); + obj = python_integer_value (arg.uint8_scalar_value ().value ()); else if (arg.is_uint16_type ()) - obj = PyLong_FromUnsignedLong (arg.uint16_scalar_value ().value ()); + obj = python_integer_value (arg.uint16_scalar_value ().value ()); else if (arg.is_uint32_type ()) - obj = PyLong_FromUnsignedLong (arg.uint32_scalar_value ().value ()); + obj = python_integer_value (arg.uint32_scalar_value ().value ()); else if (arg.is_uint64_type ()) - obj = PyLong_FromUnsignedLong (arg.uint64_scalar_value ().value ()); + obj = python_integer_value (arg.uint64_scalar_value ().value ()); else if (arg.is_bool_type ()) obj = PyBool_FromLong (arg.bool_value ()); diff -r 0d94e42bacf6 -r a133564f4af7 pycall.cc --- a/pycall.cc Tue Aug 02 13:53:12 2016 -0700 +++ b/pycall.cc Mon Aug 08 16:17:21 2016 -0700 @@ -278,6 +278,28 @@ %! assert (pycall ("roundtrip", values{i}), values{i}); %! endfor +## Test conversion of integer types into Python +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == 0"), int8 (0))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == -2**7 "), intmin ("int8"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == 2**7 -1"), intmax ("int8"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == 0"), intmin ("uint8"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == 2**8 -1"), intmax ("uint8"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == 0"), int16 (0))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == -2**15 "), intmin ("int16"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == 2**15-1"), intmax ("int16"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == 0"), intmin ("uint16"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == 2**16-1"), intmax ("uint16"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == 0"), int32 (0))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == -2**31 "), intmin ("int32"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(0) and x == 2**31-1"), intmax ("int32"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(2**64) and x == 0"), intmin ("uint32"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(2**64) and x == 2**32-1"), intmax ("uint32"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(2**64) and x == 0"), int64 (0))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(2**64) and x == -2**63 "), intmin ("int64"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(2**64) and x == 2**63-1"), intmax ("int64"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(2**64) and x == 0"), intmin ("uint64"))) +%!assert (pycall (pyeval ("lambda x: type(x) == type(2**64) and x == 2**64-1"), intmax ("uint64"))) + %!error %! pyexec ("def intwrapper(x): return int(x)"); %! pycall ("intwrapper", ftp ());