PageRenderTime 91ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/python/Lib/ctypes/test/test_pep3118.py

https://gitlab.com/pmuontains/Odoo
Python | 203 lines | 199 code | 2 blank | 2 comment | 3 complexity | 72a0c14009eaabd4a09b0780cdaa18c3 MD5 | raw file
  1. import unittest
  2. from ctypes import *
  3. import re, sys
  4. if sys.byteorder == "little":
  5. THIS_ENDIAN = "<"
  6. OTHER_ENDIAN = ">"
  7. else:
  8. THIS_ENDIAN = ">"
  9. OTHER_ENDIAN = "<"
  10. def normalize(format):
  11. # Remove current endian specifier and white space from a format
  12. # string
  13. if format is None:
  14. return ""
  15. format = format.replace(OTHER_ENDIAN, THIS_ENDIAN)
  16. return re.sub(r"\s", "", format)
  17. class Test(unittest.TestCase):
  18. def test_native_types(self):
  19. for tp, fmt, shape, itemtp in native_types:
  20. ob = tp()
  21. v = memoryview(ob)
  22. try:
  23. self.assertEqual(normalize(v.format), normalize(fmt))
  24. if shape is not None:
  25. self.assertEqual(len(v), shape[0])
  26. else:
  27. self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob))
  28. self.assertEqual(v.itemsize, sizeof(itemtp))
  29. self.assertEqual(v.shape, shape)
  30. # ctypes object always have a non-strided memory block
  31. self.assertEqual(v.strides, None)
  32. # they are always read/write
  33. self.assertFalse(v.readonly)
  34. if v.shape:
  35. n = 1
  36. for dim in v.shape:
  37. n = n * dim
  38. self.assertEqual(n * v.itemsize, len(v.tobytes()))
  39. except:
  40. # so that we can see the failing type
  41. print(tp)
  42. raise
  43. def test_endian_types(self):
  44. for tp, fmt, shape, itemtp in endian_types:
  45. ob = tp()
  46. v = memoryview(ob)
  47. try:
  48. self.assertEqual(v.format, fmt)
  49. if shape is not None:
  50. self.assertEqual(len(v), shape[0])
  51. else:
  52. self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob))
  53. self.assertEqual(v.itemsize, sizeof(itemtp))
  54. self.assertEqual(v.shape, shape)
  55. # ctypes object always have a non-strided memory block
  56. self.assertEqual(v.strides, None)
  57. # they are always read/write
  58. self.assertFalse(v.readonly)
  59. if v.shape:
  60. n = 1
  61. for dim in v.shape:
  62. n = n * dim
  63. self.assertEqual(n, len(v))
  64. except:
  65. # so that we can see the failing type
  66. print(tp)
  67. raise
  68. # define some structure classes
  69. class Point(Structure):
  70. _fields_ = [("x", c_long), ("y", c_long)]
  71. class PackedPoint(Structure):
  72. _pack_ = 2
  73. _fields_ = [("x", c_long), ("y", c_long)]
  74. class Point2(Structure):
  75. pass
  76. Point2._fields_ = [("x", c_long), ("y", c_long)]
  77. class EmptyStruct(Structure):
  78. _fields_ = []
  79. class aUnion(Union):
  80. _fields_ = [("a", c_int)]
  81. class StructWithArrays(Structure):
  82. _fields_ = [("x", c_long * 3 * 2), ("y", Point * 4)]
  83. class Incomplete(Structure):
  84. pass
  85. class Complete(Structure):
  86. pass
  87. PComplete = POINTER(Complete)
  88. Complete._fields_ = [("a", c_long)]
  89. ################################################################
  90. #
  91. # This table contains format strings as they look on little endian
  92. # machines. The test replaces '<' with '>' on big endian machines.
  93. #
  94. native_types = [
  95. # type format shape calc itemsize
  96. ## simple types
  97. (c_char, "<c", None, c_char),
  98. (c_byte, "<b", None, c_byte),
  99. (c_ubyte, "<B", None, c_ubyte),
  100. (c_short, "<h", None, c_short),
  101. (c_ushort, "<H", None, c_ushort),
  102. # c_int and c_uint may be aliases to c_long
  103. #(c_int, "<i", None, c_int),
  104. #(c_uint, "<I", None, c_uint),
  105. (c_long, "<l", None, c_long),
  106. (c_ulong, "<L", None, c_ulong),
  107. # c_longlong and c_ulonglong are aliases on 64-bit platforms
  108. #(c_longlong, "<q", None, c_longlong),
  109. #(c_ulonglong, "<Q", None, c_ulonglong),
  110. (c_float, "<f", None, c_float),
  111. (c_double, "<d", None, c_double),
  112. # c_longdouble may be an alias to c_double
  113. (c_bool, "<?", None, c_bool),
  114. (py_object, "<O", None, py_object),
  115. ## pointers
  116. (POINTER(c_byte), "&<b", None, POINTER(c_byte)),
  117. (POINTER(POINTER(c_long)), "&&<l", None, POINTER(POINTER(c_long))),
  118. ## arrays and pointers
  119. (c_double * 4, "<d", (4,), c_double),
  120. (c_float * 4 * 3 * 2, "<f", (2,3,4), c_float),
  121. (POINTER(c_short) * 2, "&<h", (2,), POINTER(c_short)),
  122. (POINTER(c_short) * 2 * 3, "&<h", (3,2,), POINTER(c_short)),
  123. (POINTER(c_short * 2), "&(2)<h", None, POINTER(c_short)),
  124. ## structures and unions
  125. (Point, "T{<l:x:<l:y:}", None, Point),
  126. # packed structures do not implement the pep
  127. (PackedPoint, "B", None, PackedPoint),
  128. (Point2, "T{<l:x:<l:y:}", None, Point2),
  129. (EmptyStruct, "T{}", None, EmptyStruct),
  130. # the pep does't support unions
  131. (aUnion, "B", None, aUnion),
  132. # structure with sub-arrays
  133. (StructWithArrays, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", None, StructWithArrays),
  134. (StructWithArrays * 3, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (3,), StructWithArrays),
  135. ## pointer to incomplete structure
  136. (Incomplete, "B", None, Incomplete),
  137. (POINTER(Incomplete), "&B", None, POINTER(Incomplete)),
  138. # 'Complete' is a structure that starts incomplete, but is completed after the
  139. # pointer type to it has been created.
  140. (Complete, "T{<l:a:}", None, Complete),
  141. # Unfortunately the pointer format string is not fixed...
  142. (POINTER(Complete), "&B", None, POINTER(Complete)),
  143. ## other
  144. # function signatures are not implemented
  145. (CFUNCTYPE(None), "X{}", None, CFUNCTYPE(None)),
  146. ]
  147. class BEPoint(BigEndianStructure):
  148. _fields_ = [("x", c_long), ("y", c_long)]
  149. class LEPoint(LittleEndianStructure):
  150. _fields_ = [("x", c_long), ("y", c_long)]
  151. ################################################################
  152. #
  153. # This table contains format strings as they really look, on both big
  154. # and little endian machines.
  155. #
  156. endian_types = [
  157. (BEPoint, "T{>l:x:>l:y:}", None, BEPoint),
  158. (LEPoint, "T{<l:x:<l:y:}", None, LEPoint),
  159. (POINTER(BEPoint), "&T{>l:x:>l:y:}", None, POINTER(BEPoint)),
  160. (POINTER(LEPoint), "&T{<l:x:<l:y:}", None, POINTER(LEPoint)),
  161. ]
  162. if __name__ == "__main__":
  163. unittest.main()