Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2)

Delta Between Two Patch Sets: Lib/ctypes/test/test_pep3118.py

Issue 10744: ctypes arrays have incorrect buffer information (PEP-3118)
Left Patch Set: Created 5 years, 9 months ago
Right Patch Set: Created 5 years, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | Modules/_ctypes/_ctypes.c » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 import unittest 1 import unittest
2 from ctypes import * 2 from ctypes import *
3 import re, sys 3 import re, struct, sys
4 4
5 if sys.byteorder == "little": 5 if sys.byteorder == "little":
6 THIS_ENDIAN = "<" 6 THIS_ENDIAN = "<"
7 OTHER_ENDIAN = ">" 7 OTHER_ENDIAN = ">"
8 else: 8 else:
9 THIS_ENDIAN = ">" 9 THIS_ENDIAN = ">"
10 OTHER_ENDIAN = "<" 10 OTHER_ENDIAN = "<"
11 11
12 def normalize(format): 12 def normalize(format):
13 # Remove current endian specifier and white space from a format 13 # Remove current endian specifier and white space from a format
14 # string 14 # string
15 if format is None: 15 if format is None:
16 return "" 16 return ""
17 format = format.replace(OTHER_ENDIAN, THIS_ENDIAN) 17 format = format.replace(OTHER_ENDIAN, THIS_ENDIAN)
18 return re.sub(r"\s", "", format) 18 return re.sub(r"\s", "", format)
19 19
20 class Test(unittest.TestCase): 20 class Test(unittest.TestCase):
21 21
22 def test_native_types(self): 22 def test_native_types(self):
23 for tp, fmt, shape, itemtp in native_types: 23 for tp, fmt, shape, itemtp in native_types:
24 ob = tp() 24 ob = tp()
25 v = memoryview(ob) 25 v = memoryview(ob)
26 try: 26 try:
27 self.assertEqual(normalize(v.format), normalize(fmt)) 27 self.assertEqual(normalize(v.format), normalize(fmt))
28 if shape is not None: 28 if shape:
29 self.assertEqual(len(v), shape[0]) 29 self.assertEqual(len(v), shape[0])
30 else: 30 else:
31 self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob)) 31 self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob))
32 self.assertEqual(v.itemsize, sizeof(itemtp)) 32 self.assertEqual(v.itemsize, sizeof(itemtp))
33 self.assertEqual(v.shape, shape) 33 self.assertEqual(v.shape, shape)
34 # ctypes object always have a non-strided memory block 34 # XXX Issue #12851: PyCData_NewGetBuffer() must provide strides
35 self.assertEqual(v.strides, None) 35 # if requested. memoryview currently reconstructs missing
36 # stride information, so this assert will fail.
37 # self.assertEqual(v.strides, ())
38
36 # they are always read/write 39 # they are always read/write
37 self.assertFalse(v.readonly) 40 self.assertFalse(v.readonly)
38 41
39 if v.shape: 42 if v.shape:
40 n = 1 43 n = 1
41 for dim in v.shape: 44 for dim in v.shape:
42 n = n * dim 45 n = n * dim
43 self.assertEqual(n * v.itemsize, len(v.tobytes())) 46 self.assertEqual(n * v.itemsize, len(v.tobytes()))
44 except: 47 except:
45 # so that we can see the failing type 48 # so that we can see the failing type
46 print(tp) 49 print(tp)
47 raise 50 raise
48 51
49 def test_endian_types(self): 52 def test_endian_types(self):
50 for tp, fmt, shape, itemtp in endian_types: 53 for tp, fmt, shape, itemtp in endian_types:
51 ob = tp() 54 ob = tp()
52 v = memoryview(ob) 55 v = memoryview(ob)
53 try: 56 try:
54 self.assertEqual(v.format, fmt) 57 self.assertEqual(v.format, fmt)
55 if shape is not None: 58 if shape:
56 self.assertEqual(len(v), shape[0]) 59 self.assertEqual(len(v), shape[0])
57 else: 60 else:
58 self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob)) 61 self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob))
59 self.assertEqual(v.itemsize, sizeof(itemtp)) 62 self.assertEqual(v.itemsize, sizeof(itemtp))
60 self.assertEqual(v.shape, shape) 63 self.assertEqual(v.shape, shape)
61 # ctypes object always have a non-strided memory block 64 # XXX Issue #12851
62 self.assertEqual(v.strides, None) 65 # self.assertEqual(v.strides, ())
66
63 # they are always read/write 67 # they are always read/write
64 self.assertFalse(v.readonly) 68 self.assertFalse(v.readonly)
65 69
66 if v.shape: 70 if v.shape:
67 n = 1 71 n = 1
68 for dim in v.shape: 72 for dim in v.shape:
69 n = n * dim 73 n = n * dim
70 self.assertEqual(n, len(v)) 74 self.assertEqual(n, len(v))
71 except: 75 except:
72 # so that we can see the failing type 76 # so that we can see the failing type
(...skipping 15 matching lines...) Expand all
88 92
89 class EmptyStruct(Structure): 93 class EmptyStruct(Structure):
90 _fields_ = [] 94 _fields_ = []
91 95
92 class aUnion(Union): 96 class aUnion(Union):
93 _fields_ = [("a", c_int)] 97 _fields_ = [("a", c_int)]
94 98
95 class StructWithArrays(Structure): 99 class StructWithArrays(Structure):
96 _fields_ = [("x", c_long * 3 * 2), ("y", Point * 4)] 100 _fields_ = [("x", c_long * 3 * 2), ("y", Point * 4)]
97 101
98
99 class Incomplete(Structure): 102 class Incomplete(Structure):
100 pass 103 pass
101 104
102 class Complete(Structure): 105 class Complete(Structure):
103 pass 106 pass
104 PComplete = POINTER(Complete) 107 PComplete = POINTER(Complete)
105 Complete._fields_ = [("a", c_long)] 108 Complete._fields_ = [("a", c_long)]
106 109
107 ################################################################ 110 ################################################################
108 # 111 #
109 # This table contains format strings as they look on little endian 112 # This table contains format strings as they look on little endian
110 # machines. The test replaces '<' with '>' on big endian machines. 113 # machines. The test replaces '<' with '>' on big endian machines.
111 # 114 #
112 native_types = [ 115 native_types = [
113 # type format shape calc ite msize 116 # type format shape calc ite msize
114 117
115 ## simple types 118 ## simple types
116 119
117 (c_char, "<c", None, c_char), 120 (c_char, "<c", (), c_char),
118 (c_byte, "<b", None, c_byte), 121 (c_byte, "<b", (), c_byte),
119 (c_ubyte, "<B", None, c_ubyte) , 122 (c_ubyte, "<B", (), c_ubyte),
120 (c_short, "<h", None, c_short) , 123 (c_short, "<h", (), c_short),
121 (c_ushort, "<H", None, c_ushort ), 124 (c_ushort, "<H", (), c_ushort),
122 125
123 # c_int and c_uint may be aliases to c_long 126 # c_int and c_uint may be aliases to c_long
124 #(c_int, "<i", None, c_int), 127 #(c_int, "<i", (), c_int),
125 #(c_uint, "<I", None, c_uint) , 128 #(c_uint, "<I", (), c_uint),
126 129
127 (c_long, "<l", None, c_long), 130 (c_long, "<l", (), c_long),
128 (c_ulong, "<L", None, c_ulong) , 131 (c_ulong, "<L", (), c_ulong),
129 132
130 # c_longlong and c_ulonglong are aliases on 64-bit platforms 133 # c_longlong and c_ulonglong are aliases on 64-bit platforms
131 #(c_longlong, "<q", None, c_longl ong), 134 #(c_longlong, "<q", None, c_longl ong),
132 #(c_ulonglong, "<Q", None, c_ulong long), 135 #(c_ulonglong, "<Q", None, c_ulong long),
133 136
134 (c_float, "<f", None, c_float) , 137 (c_float, "<f", (), c_float),
135 (c_double, "<d", None, c_double ), 138 (c_double, "<d", (), c_double),
136 # c_longdouble may be an alias to c_double 139 # c_longdouble may be an alias to c_double
137 140
138 (c_bool, "<?", None, c_bool), 141 (c_bool, "<?", (), c_bool),
139 (py_object, "<O", None, py_objec t), 142 (py_object, "<O", (), py_object) ,
140 143
141 ## pointers 144 ## pointers
142 145
143 (POINTER(c_byte), "&<b", None, POINTER( c_byte)), 146 (POINTER(c_byte), "&<b", (), POINTER(c_ byte)),
144 (POINTER(POINTER(c_long)), "&&<l", None, POINTER( POINTER(c_long))), 147 (POINTER(POINTER(c_long)), "&&<l", (), POINTER(PO INTER(c_long))),
145 148
146 ## arrays and pointers 149 ## arrays and pointers
147 150
148 (c_double * 4, "<d", (4,), c_double ), 151 (c_double * 4, "<d", (4,), c_double ),
149 (c_float * 4 * 3 * 2, "<f", (2,3,4), c_float) , 152 (c_float * 4 * 3 * 2, "<f", (2,3,4), c_float) ,
150 (POINTER(c_short) * 2, "&<h", (2,), POINTER( c_short)), 153 (POINTER(c_short) * 2, "&<h", (2,), POINTER( c_short)),
151 (POINTER(c_short) * 2 * 3, "&<h", (3,2,), POINTER( c_short)), 154 (POINTER(c_short) * 2 * 3, "&<h", (3,2,), POINTER( c_short)),
152 (POINTER(c_short * 2), "&(2)<h", None, POINTER( c_short)), 155 (POINTER(c_short * 2), "&(2)<h", (), POINTER(c_ short)),
153 156
154 ## structures and unions 157 ## structures and unions
155 158
156 (Point, "T{<l:x:<l:y:}", None, Point), 159 (Point, "T{<l:x:<l:y:}", (), Point),
157 # packed structures do not implement the pep 160 # packed structures do not implement the pep
158 (PackedPoint, "B", None, PackedPo int), 161 (PackedPoint, "B", (), PackedPoin t),
159 (Point2, "T{<l:x:<l:y:}", None, Point2), 162 (Point2, "T{<l:x:<l:y:}", (), Point2),
160 (EmptyStruct, "T{}", None, EmptyStr uct), 163 (EmptyStruct, "T{}", (), EmptyStruc t),
161 # the pep does't support unions 164 # the pep does't support unions
162 (aUnion, "B", None, aUnion), 165 (aUnion, "B", (), aUnion),
163 # structure with sub-arrays 166 # structure with sub-arrays
164 (StructWithArrays, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", None, Struc tWithArrays), 167 (StructWithArrays, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (), StructW ithArrays),
165 (StructWithArrays * 3, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (3,), Struc tWithArrays), 168 (StructWithArrays * 3, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (3,), Struc tWithArrays),
166 169
167 ## pointer to incomplete structure 170 ## pointer to incomplete structure
168 (Incomplete, "B", None, Incomple te), 171 (Incomplete, "B", (), Incomplete ),
169 (POINTER(Incomplete), "&B", None, POINTER( Incomplete)), 172 (POINTER(Incomplete), "&B", (), POINTER(In complete)),
170 173
171 # 'Complete' is a structure that starts incomplete, but is completed after t he 174 # 'Complete' is a structure that starts incomplete, but is completed after t he
172 # pointer type to it has been created. 175 # pointer type to it has been created.
173 (Complete, "T{<l:a:}", None, Complete ), 176 (Complete, "T{<l:a:}", (), Complete),
174 # Unfortunately the pointer format string is not fixed... 177 # Unfortunately the pointer format string is not fixed...
175 (POINTER(Complete), "&B", None, POINTER( Complete)), 178 (POINTER(Complete), "&B", (), POINTER(Co mplete)),
176 179
177 ## other 180 ## other
178 181
179 # function signatures are not implemented 182 # function signatures are not implemented
180 (CFUNCTYPE(None), "X{}", None, CFUNCTYP E(None)), 183 (CFUNCTYPE(None), "X{}", (), CFUNCTYPE( None)),
181 184
182 ] 185 ]
183 186
184 class BEPoint(BigEndianStructure): 187 class BEPoint(BigEndianStructure):
185 _fields_ = [("x", c_long), ("y", c_long)] 188 _fields_ = [("x", c_long), ("y", c_long)]
186 189
187 class LEPoint(LittleEndianStructure): 190 class LEPoint(LittleEndianStructure):
188 _fields_ = [("x", c_long), ("y", c_long)] 191 _fields_ = [("x", c_long), ("y", c_long)]
189 192
190 ################################################################ 193 ################################################################
191 # 194 #
192 # This table contains format strings as they really look, on both big 195 # This table contains format strings as they really look, on both big
193 # and little endian machines. 196 # and little endian machines.
194 # 197 #
195 endian_types = [ 198 endian_types = [
196 (BEPoint, "T{>l:x:>l:y:}", None, BEPoint) , 199 (BEPoint, "T{>l:x:>l:y:}", (), BEPoint),
197 (LEPoint, "T{<l:x:<l:y:}", None, LEPoint) , 200 (LEPoint, "T{<l:x:<l:y:}", (), LEPoint),
198 (POINTER(BEPoint), "&T{>l:x:>l:y:}", None, POINTER( BEPoint)), 201 (POINTER(BEPoint), "&T{>l:x:>l:y:}", (), POINTER(BE Point)),
199 (POINTER(LEPoint), "&T{<l:x:<l:y:}", None, POINTER( LEPoint)), 202 (POINTER(LEPoint), "&T{<l:x:<l:y:}", (), POINTER(LE Point)),
200 ] 203 ]
201 204
202 if __name__ == "__main__": 205 if __name__ == "__main__":
203 unittest.main() 206 unittest.main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+