1- import re
21import sys
32import unittest
43from ctypes import (CFUNCTYPE , POINTER , sizeof , Union ,
98 c_bool , c_float , c_double , c_longdouble , py_object )
109
1110
12- if sys .byteorder == "little" :
13- THIS_ENDIAN = "<"
14- OTHER_ENDIAN = ">"
15- else :
16- THIS_ENDIAN = ">"
17- OTHER_ENDIAN = "<"
18-
19-
20- def normalize (format ):
21- # Remove current endian specifier and white space from a format
22- # string
23- if format is None :
24- return ""
25- format = format .replace (OTHER_ENDIAN , THIS_ENDIAN )
26- return re .sub (r"\s" , "" , format )
27-
28-
2911class Test (unittest .TestCase ):
3012 def test_native_types (self ):
3113 for tp , fmt , shape , itemtp in native_types :
3214 ob = tp ()
3315 v = memoryview (ob )
34- self .assertEqual (normalize ( v .format ), normalize ( fmt ) )
16+ self .assertEqual (v .format , fmt )
3517 if shape :
3618 self .assertEqual (len (v ), shape [0 ])
3719 else :
@@ -73,6 +55,15 @@ def test_endian_types(self):
7355 n = n * dim
7456 self .assertEqual (n * v .itemsize , len (v .tobytes ()))
7557
58+ def test_memoryview_supports_ctypes_arrays (self ):
59+ ArrayType = c_int * 5
60+ a = ArrayType (123 , 42 , 1 , 2 , 3 )
61+ m = memoryview (a )
62+ self .assertEqual (m .shape , (5 ,))
63+ self .assertEqual (m .format , c_int ._type_ )
64+ self .assertEqual (list (m ), [123 , 42 , 1 , 2 , 3 ])
65+ self .assertEqual (m [1 ], 42 )
66+
7667
7768# define some structure classes
7869
@@ -124,8 +115,7 @@ class Complete(Structure):
124115
125116################################################################
126117#
127- # This table contains format strings as they look on little endian
128- # machines. The test replaces '<' with '>' on big endian machines.
118+ # This table contains format strings with native endianness.
129119#
130120
131121# Platform-specific type codes
@@ -160,67 +150,67 @@ class Complete(Structure):
160150
161151 ## simple types
162152
163- (c_char , "< c" , (), c_char ),
164- (c_byte , "< b" , (), c_byte ),
165- (c_ubyte , "< B" , (), c_ubyte ),
166- (c_short , "<" + s_short , (), c_short ),
167- (c_ushort , "<" + s_ushort , (), c_ushort ),
153+ (c_char , "c" , (), c_char ),
154+ (c_byte , "b" , (), c_byte ),
155+ (c_ubyte , "B" , (), c_ubyte ),
156+ (c_short , s_short , (), c_short ),
157+ (c_ushort , s_ushort , (), c_ushort ),
168158
169- (c_int , "<" + s_int , (), c_int ),
170- (c_uint , "<" + s_uint , (), c_uint ),
159+ (c_int , s_int , (), c_int ),
160+ (c_uint , s_uint , (), c_uint ),
171161
172- (c_long , "<" + s_long , (), c_long ),
173- (c_ulong , "<" + s_ulong , (), c_ulong ),
162+ (c_long , s_long , (), c_long ),
163+ (c_ulong , s_ulong , (), c_ulong ),
174164
175- (c_longlong , "<" + s_longlong , (), c_longlong ),
176- (c_ulonglong , "<" + s_ulonglong , (), c_ulonglong ),
165+ (c_longlong , s_longlong , (), c_longlong ),
166+ (c_ulonglong , s_ulonglong , (), c_ulonglong ),
177167
178- (c_float , "< f" , (), c_float ),
179- (c_double , "< d" , (), c_double ),
168+ (c_float , "f" , (), c_float ),
169+ (c_double , "d" , (), c_double ),
180170
181- (c_longdouble , "<" + s_longdouble , (), c_longdouble ),
171+ (c_longdouble , s_longdouble , (), c_longdouble ),
182172
183- (c_bool , "<" + s_bool , (), c_bool ),
184- (py_object , "< O" , (), py_object ),
173+ (c_bool , s_bool , (), c_bool ),
174+ (py_object , "O" , (), py_object ),
185175
186176 ## pointers
187177
188- (POINTER (c_byte ), "&< b" , (), POINTER (c_byte )),
189- (POINTER (POINTER (c_long )), "&&< " + s_long , (), POINTER (POINTER (c_long ))),
178+ (POINTER (c_byte ), "&b" , (), POINTER (c_byte )),
179+ (POINTER (POINTER (c_long )), "&&" + s_long , (), POINTER (POINTER (c_long ))),
190180
191181 ## arrays and pointers
192182
193- (c_double * 4 , "< d" , (4 ,), c_double ),
194- (c_double * 0 , "< d" , (0 ,), c_double ),
195- (c_float * 4 * 3 * 2 , "< f" , (2 ,3 ,4 ), c_float ),
196- (c_float * 4 * 0 * 2 , "< f" , (2 ,0 ,4 ), c_float ),
197- (POINTER (c_short ) * 2 , "&< " + s_short , (2 ,), POINTER (c_short )),
198- (POINTER (c_short ) * 2 * 3 , "&< " + s_short , (3 ,2 ,), POINTER (c_short )),
199- (POINTER (c_short * 2 ), "&(2)< " + s_short , (), POINTER (c_short )),
183+ (c_double * 4 , "d" , (4 ,), c_double ),
184+ (c_double * 0 , "d" , (0 ,), c_double ),
185+ (c_float * 4 * 3 * 2 , "f" , (2 ,3 ,4 ), c_float ),
186+ (c_float * 4 * 0 * 2 , "f" , (2 ,0 ,4 ), c_float ),
187+ (POINTER (c_short ) * 2 , "&" + s_short , (2 ,), POINTER (c_short )),
188+ (POINTER (c_short ) * 2 * 3 , "&" + s_short , (3 ,2 ,), POINTER (c_short )),
189+ (POINTER (c_short * 2 ), "&(2)" + s_short , (), POINTER (c_short )),
200190
201191 ## structures and unions
202192
203- (Point2 , "T{< l:x:< l:y:}" .replace ('l' , s_long ), (), Point2 ),
204- (Point , "T{< l:x:< l:y:}" .replace ('l' , s_long ), (), Point ),
205- (PackedPoint , "T{< l:x:< l:y:}" .replace ('l' , s_long ), (), PackedPoint ),
206- (PointMidPad , "T{< b:x:3x<I :y:}" .replace ('I' , s_uint ), (), PointMidPad ),
207- (PackedPointMidPad , "T{< b:x:x<Q :y:}" , (), PackedPointMidPad ),
208- (PointEndPad , "T{< I:x:< b:y:3x}" .replace ('I' , s_uint ), (), PointEndPad ),
209- (PackedPointEndPad , "T{< Q:x:< b:y:x}" , (), PackedPointEndPad ),
210- (EmptyStruct , "T{}" , (), EmptyStruct ),
193+ (Point2 , "T{l:x:l:y:}" .replace ('l' , s_long ), (), Point2 ),
194+ (Point , "T{l:x:l:y:}" .replace ('l' , s_long ), (), Point ),
195+ (PackedPoint , "T{l:x:l:y:}" .replace ('l' , s_long ), (), PackedPoint ),
196+ (PointMidPad , "T{b:x:3xI :y:}" .replace ('I' , s_uint ), (), PointMidPad ),
197+ (PackedPointMidPad , "T{b:x:xQ :y:}" , (), PackedPointMidPad ),
198+ (PointEndPad , "T{I:x:b:y:3x}" .replace ('I' , s_uint ), (), PointEndPad ),
199+ (PackedPointEndPad , "T{Q:x:b:y:x}" , (), PackedPointEndPad ),
200+ (EmptyStruct , "T{}" , (), EmptyStruct ),
211201 # the pep doesn't support unions
212- (aUnion , "B" , (), aUnion ),
202+ (aUnion , "B" , (), aUnion ),
213203 # structure with sub-arrays
214- (StructWithArrays , "T{(2,3)< l:x:(4)T{< l:x:< l:y:}:y:}" .replace ('l' , s_long ), (), StructWithArrays ),
215- (StructWithArrays * 3 , "T{(2,3)< l:x:(4)T{< l:x:< l:y:}:y:}" .replace ('l' , s_long ), (3 ,), StructWithArrays ),
204+ (StructWithArrays , "T{(2,3)l:x:(4)T{l:x:l:y:}:y:}" .replace ('l' , s_long ), (), StructWithArrays ),
205+ (StructWithArrays * 3 , "T{(2,3)l:x:(4)T{l:x:l:y:}:y:}" .replace ('l' , s_long ), (3 ,), StructWithArrays ),
216206
217207 ## pointer to incomplete structure
218208 (Incomplete , "B" , (), Incomplete ),
219209 (POINTER (Incomplete ), "&B" , (), POINTER (Incomplete )),
220210
221211 # 'Complete' is a structure that starts incomplete, but is completed after the
222212 # pointer type to it has been created.
223- (Complete , "T{< l:a:}" .replace ('l' , s_long ), (), Complete ),
213+ (Complete , "T{l:a:}" .replace ('l' , s_long ), (), Complete ),
224214 # Unfortunately the pointer format string is not fixed...
225215 (POINTER (Complete ), "&B" , (), POINTER (Complete )),
226216
@@ -241,12 +231,20 @@ class LEPoint(LittleEndianStructure):
241231
242232# This table contains format strings as they really look, on both big
243233# and little endian machines.
244- endian_types = [
245- (BEPoint , "T{>l:x:>l:y:}" .replace ('l' , s_long ), (), BEPoint ),
246- (LEPoint * 1 , "T{<l:x:<l:y:}" .replace ('l' , s_long ), (1 ,), LEPoint ),
247- (POINTER (BEPoint ), "&T{>l:x:>l:y:}" .replace ('l' , s_long ), (), POINTER (BEPoint )),
248- (POINTER (LEPoint ), "&T{<l:x:<l:y:}" .replace ('l' , s_long ), (), POINTER (LEPoint )),
249- ]
234+ if sys .byteorder == "little" :
235+ endian_types = [
236+ (BEPoint , "T{>l:x:>l:y:}" .replace ('l' , s_long ), (), BEPoint ),
237+ (LEPoint * 1 , "T{l:x:l:y:}" .replace ('l' , s_long ), (1 ,), LEPoint ),
238+ (POINTER (BEPoint ), "&T{>l:x:>l:y:}" .replace ('l' , s_long ), (), POINTER (BEPoint )),
239+ (POINTER (LEPoint ), "&T{l:x:l:y:}" .replace ('l' , s_long ), (), POINTER (LEPoint )),
240+ ]
241+ else :
242+ endian_types = [
243+ (BEPoint * 1 , "T{l:x:l:y:}" .replace ('l' , s_long ), (1 ,), BEPoint ),
244+ (LEPoint , "T{<l:x:<l:y:}" .replace ('l' , s_long ), (), LEPoint ),
245+ (POINTER (BEPoint ), "&T{l:x:l:y:}" .replace ('l' , s_long ), (), POINTER (BEPoint )),
246+ (POINTER (LEPoint ), "&T{<l:x:<l:y:}" .replace ('l' , s_long ), (), POINTER (LEPoint )),
247+ ]
250248
251249
252250if __name__ == "__main__" :
0 commit comments