10a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom ctypes import *
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport struct
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef valid_ranges(*types):
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # given a sequence of numeric types, collect their _type_
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # attribute, which is a single format character compatible with
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # the struct module, use the struct module to calculate the
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # minimum and maximum value allowed for this format.
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Returns a list of (min, max) values.
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    result = []
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for t in types:
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fmt = t._type_
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        size = struct.calcsize(fmt)
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = struct.unpack(fmt, ("\x00"*32)[:size])[0]
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = struct.unpack(fmt, ("\xFF"*32)[:size])[0]
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        c = struct.unpack(fmt, ("\x7F"+"\x00"*32)[:size])[0]
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = struct.unpack(fmt, ("\x80"+"\xFF"*32)[:size])[0]
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        result.append((min(a, b, c, d), max(a, b, c, d)))
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return result
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
220a8c90248264a8b26970b4473770bcc3df8515fJosh GaoArgType = type(byref(c_int(0)))
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaounsigned_types = [c_ubyte, c_ushort, c_uint, c_ulong]
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gaosigned_types = [c_byte, c_short, c_int, c_long, c_longlong]
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gaobool_types = []
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofloat_types = [c_double, c_float]
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry:
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    c_ulonglong
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    c_longlong
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept NameError:
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    pass
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoelse:
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    unsigned_types.append(c_ulonglong)
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    signed_types.append(c_longlong)
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry:
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    c_bool
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept NameError:
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    pass
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoelse:
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    bool_types.append(c_bool)
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gaounsigned_ranges = valid_ranges(*unsigned_types)
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gaosigned_ranges = valid_ranges(*signed_types)
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gaobool_values = [True, False, 0, 1, -1, 5000, 'test', [], [1]]
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao################################################################
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass NumberTestCase(unittest.TestCase):
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_default_init(self):
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # default values are set to zero
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in signed_types + unsigned_types + float_types:
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t().value, 0)
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_unsigned_values(self):
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # the value given to the constructor is available
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # as the 'value' attribute
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t, (l, h) in zip(unsigned_types, unsigned_ranges):
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t(l).value, l)
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t(h).value, h)
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_signed_values(self):
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # see above
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t, (l, h) in zip(signed_types, signed_ranges):
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t(l).value, l)
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t(h).value, h)
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bool_values(self):
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from operator import truth
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t, v in zip(bool_types, bool_values):
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t(v).value, truth(v))
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_typeerror(self):
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Only numbers are allowed in the contructor,
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # otherwise TypeError is raised
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in signed_types + unsigned_types + float_types:
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, t, "")
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, t, None)
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao##    def test_valid_ranges(self):
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao##        # invalid values of the correct type
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao##        # raise ValueError (not OverflowError)
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao##        for t, (l, h) in zip(unsigned_types, unsigned_ranges):
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao##            self.assertRaises(ValueError, t, l-1)
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao##            self.assertRaises(ValueError, t, h+1)
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_from_param(self):
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # the from_param class method attribute always
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # returns PyCArgObject instances
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in signed_types + unsigned_types + float_types:
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(ArgType, type(t.from_param(0)))
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_byref(self):
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # calling byref returns also a PyCArgObject instance
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in signed_types + unsigned_types + float_types + bool_types:
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            parm = byref(t())
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(ArgType, type(parm))
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_floats(self):
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # c_float and c_double can be created from
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Python int, long and float
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class FloatLike(object):
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __float__(self):
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 2.0
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = FloatLike()
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in float_types:
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t(2.0).value, 2.0)
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t(2).value, 2.0)
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t(2L).value, 2.0)
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t(f).value, 2.0)
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_integers(self):
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class FloatLike(object):
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __float__(self):
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 2.0
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = FloatLike()
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class IntLike(object):
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __int__(self):
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 2
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = IntLike()
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # integers cannot be constructed from floats,
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # but from integer-like objects
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in signed_types + unsigned_types:
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, t, 3.14)
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, t, f)
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t(i).value, 2)
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_sizes(self):
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in signed_types + unsigned_types + float_types + bool_types:
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                size = struct.calcsize(t._type_)
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except struct.error:
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                continue
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # sizeof of the type...
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(sizeof(t), size)
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # and sizeof of an instance
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(sizeof(t()), size)
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_alignments(self):
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in signed_types + unsigned_types + float_types:
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            code = t._type_ # the typecode
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            align = struct.calcsize("c%c" % code) - struct.calcsize(code)
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # alignment of the type...
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual((code, alignment(t)),
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 (code, align))
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # and alignment of an instance
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual((code, alignment(t())),
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 (code, align))
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_int_from_address(self):
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from array import array
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in signed_types + unsigned_types:
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # the array module doesn't support all format codes
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # (no 'q' or 'Q')
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                array(t._type_)
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except ValueError:
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                continue
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            a = array(t._type_, [100])
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # v now is an integer at an 'external' memory location
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            v = t.from_address(a.buffer_info()[0])
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(v.value, a[0])
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(type(v), t)
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # changing the value at the memory location changes v's value also
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            a[0] = 42
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(v.value, a[0])
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_float_from_address(self):
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from array import array
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in float_types:
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            a = array(t._type_, [3.14])
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            v = t.from_address(a.buffer_info()[0])
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(v.value, a[0])
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(type(v) is t)
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            a[0] = 2.3456e17
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(v.value, a[0])
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(type(v) is t)
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_char_from_address(self):
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from ctypes import c_char
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from array import array
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = array('c', 'x')
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        v = c_char.from_address(a.buffer_info()[0])
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(v.value, a[0])
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(type(v) is c_char)
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a[0] = '?'
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(v.value, a[0])
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # array does not support c_bool / 't'
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # def test_bool_from_address(self):
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #     from ctypes import c_bool
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #     from array import array
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #     a = array(c_bool._type_, [True])
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #     v = t.from_address(a.buffer_info()[0])
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #     self.assertEqual(v.value, a[0])
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #     self.assertEqual(type(v) is t)
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #     a[0] = False
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #     self.assertEqual(v.value, a[0])
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #     self.assertEqual(type(v) is t)
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_init(self):
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # c_int() can be initialized from Python's int, and c_int.
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Not from c_long or so, which seems strange, abd should
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # probably be changed:
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, c_int, c_long(42))
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_float_overflow(self):
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import sys
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        big_int = int(sys.float_info.max) * 2
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in float_types + [c_longdouble]:
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(OverflowError, t, big_int)
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if (hasattr(t, "__ctype_be__")):
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertRaises(OverflowError, t.__ctype_be__, big_int)
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if (hasattr(t, "__ctype_le__")):
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertRaises(OverflowError, t.__ctype_le__, big_int)
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao##    def test_perf(self):
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao##        check_perf()
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom ctypes import _SimpleCData
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass c_int_S(_SimpleCData):
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _type_ = "i"
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    __slots__ = []
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef run_test(rep, msg, func, arg=None):
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao##    items = [None] * rep
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    items = range(rep)
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    from time import clock
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if arg is not None:
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        start = clock()
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in items:
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            func(arg); func(arg); func(arg); func(arg); func(arg)
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        stop = clock()
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        start = clock()
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in items:
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            func(); func(); func(); func(); func()
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        stop = clock()
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    print "%15s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef check_perf():
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Construct 5 objects
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    from ctypes import c_int
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    REP = 200000
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    run_test(REP, "int()", int)
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    run_test(REP, "int(999)", int)
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    run_test(REP, "c_int()", c_int)
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    run_test(REP, "c_int(999)", c_int)
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    run_test(REP, "c_int_S()", c_int_S)
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    run_test(REP, "c_int_S(999)", c_int_S)
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Python 2.3 -OO, win2k, P4 700 MHz:
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#          int(): 0.87 us
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#       int(999): 0.87 us
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#        c_int(): 3.35 us
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#     c_int(999): 3.34 us
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#      c_int_S(): 3.23 us
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   c_int_S(999): 3.24 us
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Python 2.2 -OO, win2k, P4 700 MHz:
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#          int(): 0.89 us
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#       int(999): 0.89 us
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#        c_int(): 9.99 us
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#     c_int(999): 10.02 us
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#      c_int_S(): 9.87 us
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   c_int_S(999): 9.85 us
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__':
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao##    check_perf()
2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    unittest.main()
287