14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom ctypes import *
24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport unittest
34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport struct
44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef valid_ranges(*types):
64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # given a sequence of numeric types, collect their _type_
74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # attribute, which is a single format character compatible with
84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # the struct module, use the struct module to calculate the
94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # minimum and maximum value allowed for this format.
104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # Returns a list of (min, max) values.
114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    result = []
124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    for t in types:
134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        fmt = t._type_
144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        size = struct.calcsize(fmt)
154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        a = struct.unpack(fmt, ("\x00"*32)[:size])[0]
164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        b = struct.unpack(fmt, ("\xFF"*32)[:size])[0]
174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        c = struct.unpack(fmt, ("\x7F"+"\x00"*32)[:size])[0]
184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        d = struct.unpack(fmt, ("\x80"+"\xFF"*32)[:size])[0]
194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        result.append((min(a, b, c, d), max(a, b, c, d)))
204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return result
214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
224adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoArgType = type(byref(c_int(0)))
234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaounsigned_types = [c_ubyte, c_ushort, c_uint, c_ulong]
254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaosigned_types = [c_byte, c_short, c_int, c_long, c_longlong]
264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaobool_types = []
284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofloat_types = [c_double, c_float]
304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotry:
324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    c_ulonglong
334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    c_longlong
344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoexcept NameError:
354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    pass
364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoelse:
374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    unsigned_types.append(c_ulonglong)
384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    signed_types.append(c_longlong)
394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotry:
414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    c_bool
424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoexcept NameError:
434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    pass
444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoelse:
454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    bool_types.append(c_bool)
464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaounsigned_ranges = valid_ranges(*unsigned_types)
484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaosigned_ranges = valid_ranges(*signed_types)
494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaobool_values = [True, False, 0, 1, -1, 5000, 'test', [], [1]]
504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao################################################################
524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass NumberTestCase(unittest.TestCase):
544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_default_init(self):
564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # default values are set to zero
574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in signed_types + unsigned_types + float_types:
584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t().value, 0)
594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_unsigned_values(self):
614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # the value given to the constructor is available
624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # as the 'value' attribute
634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t, (l, h) in zip(unsigned_types, unsigned_ranges):
644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t(l).value, l)
654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t(h).value, h)
664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_signed_values(self):
684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # see above
694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t, (l, h) in zip(signed_types, signed_ranges):
704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t(l).value, l)
714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t(h).value, h)
724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_bool_values(self):
744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        from operator import truth
754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t, v in zip(bool_types, bool_values):
764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t(v).value, truth(v))
774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_typeerror(self):
794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Only numbers are allowed in the contructor,
804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # otherwise TypeError is raised
814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in signed_types + unsigned_types + float_types:
824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(TypeError, t, "")
834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(TypeError, t, None)
844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao##    def test_valid_ranges(self):
864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao##        # invalid values of the correct type
874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao##        # raise ValueError (not OverflowError)
884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao##        for t, (l, h) in zip(unsigned_types, unsigned_ranges):
894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao##            self.assertRaises(ValueError, t, l-1)
904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao##            self.assertRaises(ValueError, t, h+1)
914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_from_param(self):
934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # the from_param class method attribute always
944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # returns PyCArgObject instances
954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in signed_types + unsigned_types + float_types:
964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(ArgType, type(t.from_param(0)))
974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_byref(self):
994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # calling byref returns also a PyCArgObject instance
1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in signed_types + unsigned_types + float_types + bool_types:
1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            parm = byref(t())
1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(ArgType, type(parm))
1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_floats(self):
1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # c_float and c_double can be created from
1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Python int, long and float
1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        class FloatLike(object):
1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            def __float__(self):
1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return 2.0
1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = FloatLike()
1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in float_types:
1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t(2.0).value, 2.0)
1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t(2).value, 2.0)
1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t(2L).value, 2.0)
1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t(f).value, 2.0)
1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_integers(self):
1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        class FloatLike(object):
1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            def __float__(self):
1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return 2.0
1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = FloatLike()
1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        class IntLike(object):
1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            def __int__(self):
1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return 2
1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        i = IntLike()
1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # integers cannot be constructed from floats,
1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # but from integer-like objects
1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in signed_types + unsigned_types:
1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(TypeError, t, 3.14)
1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(TypeError, t, f)
1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(t(i).value, 2)
1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_sizes(self):
1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in signed_types + unsigned_types + float_types + bool_types:
1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            try:
1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                size = struct.calcsize(t._type_)
1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            except struct.error:
1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                continue
1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # sizeof of the type...
1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(sizeof(t), size)
1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # and sizeof of an instance
1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(sizeof(t()), size)
1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_alignments(self):
1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in signed_types + unsigned_types + float_types:
1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            code = t._type_ # the typecode
1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            align = struct.calcsize("c%c" % code) - struct.calcsize(code)
1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # alignment of the type...
1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual((code, alignment(t)),
1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                 (code, align))
1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # and alignment of an instance
1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual((code, alignment(t())),
1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                 (code, align))
1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_int_from_address(self):
1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        from array import array
1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in signed_types + unsigned_types:
1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # the array module doesn't support all format codes
1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # (no 'q' or 'Q')
1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            try:
1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                array(t._type_)
1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            except ValueError:
1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                continue
1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            a = array(t._type_, [100])
1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # v now is an integer at an 'external' memory location
1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            v = t.from_address(a.buffer_info()[0])
1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(v.value, a[0])
1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(type(v), t)
1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # changing the value at the memory location changes v's value also
1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            a[0] = 42
1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(v.value, a[0])
1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_float_from_address(self):
1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        from array import array
1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in float_types:
1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            a = array(t._type_, [3.14])
1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            v = t.from_address(a.buffer_info()[0])
1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(v.value, a[0])
1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertTrue(type(v) is t)
1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            a[0] = 2.3456e17
1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(v.value, a[0])
1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertTrue(type(v) is t)
1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_char_from_address(self):
1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        from ctypes import c_char
1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        from array import array
1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        a = array('c', 'x')
1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        v = c_char.from_address(a.buffer_info()[0])
1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(v.value, a[0])
1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertTrue(type(v) is c_char)
1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        a[0] = '?'
1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(v.value, a[0])
2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # array does not support c_bool / 't'
2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # def test_bool_from_address(self):
2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     from ctypes import c_bool
2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     from array import array
2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     a = array(c_bool._type_, [True])
2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     v = t.from_address(a.buffer_info()[0])
2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     self.assertEqual(v.value, a[0])
2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     self.assertEqual(type(v) is t)
2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     a[0] = False
2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     self.assertEqual(v.value, a[0])
2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     self.assertEqual(type(v) is t)
2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_init(self):
2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # c_int() can be initialized from Python's int, and c_int.
2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Not from c_long or so, which seems strange, abd should
2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # probably be changed:
2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(TypeError, c_int, c_long(42))
2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_float_overflow(self):
2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        import sys
2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        big_int = int(sys.float_info.max) * 2
2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for t in float_types + [c_longdouble]:
2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(OverflowError, t, big_int)
2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if (hasattr(t, "__ctype_be__")):
2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.assertRaises(OverflowError, t.__ctype_be__, big_int)
2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if (hasattr(t, "__ctype_le__")):
2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.assertRaises(OverflowError, t.__ctype_le__, big_int)
2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao##    def test_perf(self):
2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao##        check_perf()
2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom ctypes import _SimpleCData
2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass c_int_S(_SimpleCData):
2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    _type_ = "i"
2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    __slots__ = []
2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef run_test(rep, msg, func, arg=None):
2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao##    items = [None] * rep
2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    items = range(rep)
2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    from time import clock
2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if arg is not None:
2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        start = clock()
2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for i in items:
2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            func(arg); func(arg); func(arg); func(arg); func(arg)
2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        stop = clock()
2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        start = clock()
2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for i in items:
2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            func(); func(); func(); func(); func()
2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        stop = clock()
2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print "%15s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))
2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef check_perf():
2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # Construct 5 objects
2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    from ctypes import c_int
2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    REP = 200000
2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    run_test(REP, "int()", int)
2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    run_test(REP, "int(999)", int)
2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    run_test(REP, "c_int()", c_int)
2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    run_test(REP, "c_int(999)", c_int)
2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    run_test(REP, "c_int_S()", c_int_S)
2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    run_test(REP, "c_int_S(999)", c_int_S)
2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Python 2.3 -OO, win2k, P4 700 MHz:
2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#
2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#          int(): 0.87 us
2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#       int(999): 0.87 us
2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#        c_int(): 3.35 us
2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#     c_int(999): 3.34 us
2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#      c_int_S(): 3.23 us
2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#   c_int_S(999): 3.24 us
2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Python 2.2 -OO, win2k, P4 700 MHz:
2764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#
2774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#          int(): 0.89 us
2784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#       int(999): 0.89 us
2794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#        c_int(): 9.99 us
2804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#     c_int(999): 10.02 us
2814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#      c_int_S(): 9.87 us
2824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#   c_int_S(999): 9.85 us
2834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == '__main__':
2854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao##    check_perf()
2864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    unittest.main()
287