PageRenderTime 78ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/lib-python/modified-2.5.2/ctypes/test/test_numbers.py

https://github.com/lalitjsraks/pypy
Python | 246 lines | 222 code | 12 blank | 12 comment | 8 complexity | 25ea86b4227575d370212508dc5841bb MD5 | raw file
  1. from ctypes import *
  2. import unittest
  3. import sys, struct
  4. def valid_ranges(*types):
  5. # given a sequence of numeric types, collect their _type_
  6. # attribute, which is a single format character compatible with
  7. # the struct module, use the struct module to calculate the
  8. # minimum and maximum value allowed for this format.
  9. # Returns a list of (min, max) values.
  10. result = []
  11. for t in types:
  12. fmt = t._type_
  13. size = struct.calcsize(fmt)
  14. a = struct.unpack(fmt, ("\x00"*32)[:size])[0]
  15. b = struct.unpack(fmt, ("\xFF"*32)[:size])[0]
  16. c = struct.unpack(fmt, ("\x7F"+"\x00"*32)[:size])[0]
  17. d = struct.unpack(fmt, ("\x80"+"\xFF"*32)[:size])[0]
  18. result.append((min(a, b, c, d), max(a, b, c, d)))
  19. return result
  20. ArgType = type(byref(c_int(0)))
  21. unsigned_types = [c_ubyte, c_ushort, c_uint, c_ulong]
  22. signed_types = [c_byte, c_short, c_int, c_long, c_longlong]
  23. float_types = [c_double, c_float]
  24. try:
  25. c_ulonglong
  26. c_longlong
  27. except NameError:
  28. pass
  29. else:
  30. unsigned_types.append(c_ulonglong)
  31. signed_types.append(c_longlong)
  32. unsigned_ranges = valid_ranges(*unsigned_types)
  33. signed_ranges = valid_ranges(*signed_types)
  34. ################################################################
  35. class NumberTestCase(unittest.TestCase):
  36. def test_default_init(self):
  37. # default values are set to zero
  38. for t in signed_types + unsigned_types + float_types:
  39. self.failUnlessEqual(t().value, 0)
  40. def test_unsigned_values(self):
  41. # the value given to the constructor is available
  42. # as the 'value' attribute
  43. for t, (l, h) in zip(unsigned_types, unsigned_ranges):
  44. self.failUnlessEqual(t(l).value, l)
  45. self.failUnlessEqual(t(h).value, h)
  46. def test_signed_values(self):
  47. # see above
  48. for t, (l, h) in zip(signed_types, signed_ranges):
  49. self.failUnlessEqual(t(l).value, l)
  50. self.failUnlessEqual(t(h).value, h)
  51. def test_typeerror(self):
  52. # Only numbers are allowed in the contructor,
  53. # otherwise TypeError is raised
  54. for t in signed_types + unsigned_types + float_types:
  55. self.assertRaises(TypeError, t, "")
  56. self.assertRaises(TypeError, t, None)
  57. ## def test_valid_ranges(self):
  58. ## # invalid values of the correct type
  59. ## # raise ValueError (not OverflowError)
  60. ## for t, (l, h) in zip(unsigned_types, unsigned_ranges):
  61. ## self.assertRaises(ValueError, t, l-1)
  62. ## self.assertRaises(ValueError, t, h+1)
  63. def test_from_param(self):
  64. # the from_param class method attribute always
  65. # returns PyCArgObject instances
  66. for t in signed_types + unsigned_types + float_types:
  67. self.failUnlessEqual(ArgType, type(t.from_param(0)))
  68. def test_byref(self):
  69. # calling byref returns also a PyCArgObject instance
  70. for t in signed_types + unsigned_types + float_types:
  71. parm = byref(t())
  72. self.failUnlessEqual(ArgType, type(parm))
  73. def test_floats(self):
  74. # c_float and c_double can be created from
  75. # Python int, long and float
  76. class FloatLike(object):
  77. def __float__(self):
  78. return 2.0
  79. f = FloatLike()
  80. for t in float_types:
  81. self.failUnlessEqual(t(2.0).value, 2.0)
  82. self.failUnlessEqual(t(2).value, 2.0)
  83. self.failUnlessEqual(t(2L).value, 2.0)
  84. self.failUnlessEqual(t(f).value, 2.0)
  85. def test_integers(self):
  86. class FloatLike(object):
  87. def __float__(self):
  88. return 2.0
  89. f = FloatLike()
  90. class IntLike(object):
  91. def __int__(self):
  92. return 2
  93. i = IntLike()
  94. # integers cannot be constructed from floats,
  95. # but from integer-like objects
  96. for t in signed_types + unsigned_types:
  97. self.assertRaises(TypeError, t, 3.14)
  98. self.assertRaises(TypeError, t, f)
  99. self.failUnlessEqual(t(i).value, 2)
  100. def test_sizes(self):
  101. for t in signed_types + unsigned_types + float_types:
  102. size = struct.calcsize(t._type_)
  103. # sizeof of the type...
  104. self.failUnlessEqual(sizeof(t), size)
  105. # and sizeof of an instance
  106. self.failUnlessEqual(sizeof(t()), size)
  107. def test_alignments(self):
  108. for t in signed_types + unsigned_types + float_types:
  109. code = t._type_ # the typecode
  110. align = struct.calcsize("c%c" % code) - struct.calcsize(code)
  111. # alignment of the type...
  112. self.failUnlessEqual((code, alignment(t)),
  113. (code, align))
  114. # and alignment of an instance
  115. self.failUnlessEqual((code, alignment(t())),
  116. (code, align))
  117. def test_int_from_address(self):
  118. from array import array
  119. for t in signed_types + unsigned_types:
  120. # the array module doesn't suppport all format codes
  121. # (no 'q' or 'Q')
  122. try:
  123. array(t._type_)
  124. except ValueError:
  125. continue
  126. a = array(t._type_, [100])
  127. # v now is an integer at an 'external' memory location
  128. v = t.from_address(a.buffer_info()[0])
  129. self.failUnlessEqual(v.value, a[0])
  130. self.failUnlessEqual(type(v), t)
  131. # changing the value at the memory location changes v's value also
  132. a[0] = 42
  133. self.failUnlessEqual(v.value, a[0])
  134. def test_float_from_address(self):
  135. from array import array
  136. for t in float_types:
  137. a = array(t._type_, [3.14])
  138. v = t.from_address(a.buffer_info()[0])
  139. self.failUnlessEqual(v.value, a[0])
  140. self.failUnless(type(v) is t)
  141. a[0] = 2.3456e17
  142. self.failUnlessEqual(v.value, a[0])
  143. self.failUnless(type(v) is t)
  144. def test_char_from_address(self):
  145. from ctypes import c_char
  146. from array import array
  147. a = array('c', 'x')
  148. v = c_char.from_address(a.buffer_info()[0])
  149. self.failUnlessEqual(v.value, a[0])
  150. self.failUnless(type(v) is c_char)
  151. a[0] = '?'
  152. self.failUnlessEqual(v.value, a[0])
  153. def test_init(self):
  154. # c_int() can be initialized from Python's int, and c_int.
  155. # Not from c_long or so, which seems strange, abd should
  156. # probably be changed:
  157. self.assertRaises(TypeError, c_int, c_long(42))
  158. ## def test_perf(self):
  159. ## check_perf()
  160. from ctypes import _SimpleCData
  161. class c_int_S(_SimpleCData):
  162. _type_ = "i"
  163. __slots__ = []
  164. def run_test(rep, msg, func, arg=None):
  165. ## items = [None] * rep
  166. items = range(rep)
  167. from time import clock
  168. if arg is not None:
  169. start = clock()
  170. for i in items:
  171. func(arg); func(arg); func(arg); func(arg); func(arg)
  172. stop = clock()
  173. else:
  174. start = clock()
  175. for i in items:
  176. func(); func(); func(); func(); func()
  177. stop = clock()
  178. print "%15s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))
  179. def check_perf():
  180. # Construct 5 objects
  181. from ctypes import c_int
  182. REP = 200000
  183. run_test(REP, "int()", int)
  184. run_test(REP, "int(999)", int)
  185. run_test(REP, "c_int()", c_int)
  186. run_test(REP, "c_int(999)", c_int)
  187. run_test(REP, "c_int_S()", c_int_S)
  188. run_test(REP, "c_int_S(999)", c_int_S)
  189. # Python 2.3 -OO, win2k, P4 700 MHz:
  190. #
  191. # int(): 0.87 us
  192. # int(999): 0.87 us
  193. # c_int(): 3.35 us
  194. # c_int(999): 3.34 us
  195. # c_int_S(): 3.23 us
  196. # c_int_S(999): 3.24 us
  197. # Python 2.2 -OO, win2k, P4 700 MHz:
  198. #
  199. # int(): 0.89 us
  200. # int(999): 0.89 us
  201. # c_int(): 9.99 us
  202. # c_int(999): 10.02 us
  203. # c_int_S(): 9.87 us
  204. # c_int_S(999): 9.85 us
  205. if __name__ == '__main__':
  206. ## check_perf()
  207. unittest.main()