@@ -7030,24 +7030,36 @@ def aligned(n):
7030
7030
return align * (1 + (n - 1 )// align )
7031
7031
7032
7032
base = dict (formats = ['i' ], names = ['f0' ])
7033
+ bbase = dict (formats = ['b' ], names = ['f0' ])
7033
7034
7034
7035
self ._check ('ix' , dict (itemsize = size + 1 , ** base ))
7035
7036
self ._check ('ixx' , dict (itemsize = size + 2 , ** base ))
7036
7037
self ._check ('ixxx' , dict (itemsize = size + 3 , ** base ))
7037
7038
self ._check ('ixxxx' , dict (itemsize = size + 4 , ** base ))
7038
7039
self ._check ('i7x' , dict (itemsize = size + 7 , ** base ))
7039
-
7040
- self ._check ('T{i:f0:x}' , dict (itemsize = aligned (size + 1 ), ** base ))
7041
- self ._check ('T{i:f0:xx}' , dict (itemsize = aligned (size + 2 ), ** base ))
7042
- self ._check ('T{i:f0:xxx}' , dict (itemsize = aligned (size + 3 ), ** base ))
7043
- self ._check ('T{i:f0:xxxx}' , dict (itemsize = aligned (size + 4 ), ** base ))
7044
- self ._check ('T{i:f0:7x}' , dict (itemsize = aligned (size + 7 ), ** base ))
7040
+ self ._check ('ix0i' , dict (itemsize = 2 * size , ** base ))
7041
+ self ._check ('b0i' , dict (itemsize = size , ** bbase ))
7042
+
7043
+ # Our intepretaton of the PEP3118/struct spec is that trailing
7044
+ # padding for alignment is assumed only inside of T{}.
7045
+ self ._check ('T{ix}' , dict (itemsize = aligned (size + 1 ), ** base ))
7046
+ self ._check ('T{ixx}' , dict (itemsize = aligned (size + 2 ), ** base ))
7047
+ self ._check ('T{ixxx}' , dict (itemsize = aligned (size + 3 ), ** base ))
7048
+ self ._check ('T{ixxxx}' , dict (itemsize = aligned (size + 4 ), ** base ))
7049
+ self ._check ('T{i7x}' , dict (itemsize = aligned (size + 7 ), ** base ))
7050
+ self ._check ('T{ix0i}' , dict (itemsize = 2 * size , ** base ))
7051
+ self ._check ('T{b0i}' , dict (itemsize = size , ** bbase ))
7052
+
7053
+ # check that alignment mode affects assumed trailing padding in T{}
7054
+ self ._check ('T{=ix}' , dict (itemsize = size + 1 , ** base ))
7045
7055
7046
7056
self ._check ('^ix' , dict (itemsize = size + 1 , ** base ))
7047
7057
self ._check ('^ixx' , dict (itemsize = size + 2 , ** base ))
7048
7058
self ._check ('^ixxx' , dict (itemsize = size + 3 , ** base ))
7049
7059
self ._check ('^ixxxx' , dict (itemsize = size + 4 , ** base ))
7050
7060
self ._check ('^i7x' , dict (itemsize = size + 7 , ** base ))
7061
+ self ._check ('^ixx0i' , dict (itemsize = size + 2 , ** base ))
7062
+ self ._check ('^b0i' , np .dtype ('b' ))
7051
7063
7052
7064
# check we can convert to memoryview and back, aligned and unaligned
7053
7065
arr = np .zeros (3 , dtype = np .dtype ('u1,i4,u1' , align = True ))
@@ -7056,6 +7068,28 @@ def aligned(n):
7056
7068
arr = np .zeros (3 , dtype = np .dtype ('u1,i4,u1' , align = False ))
7057
7069
assert_equal (arr .dtype , np .array (memoryview (arr )).dtype )
7058
7070
7071
+ a = np .empty (0 , np .dtype ({'formats' : ['u1' ], 'offsets' : [0 ],
7072
+ 'names' : ['x' ], 'itemsize' : 4 }))
7073
+ assert_equal (a , np .array (memoryview (a )))
7074
+
7075
+ # check that 0-sized elements act as padding in @ alignment and not =
7076
+ # outside of T{} (see python struct docs, example at very end)
7077
+ self ._check ('B:f0:B:f1:' , [('f0' , 'u1' ), ('f1' , 'u1' )])
7078
+ self ._check ('B:f0:0iB:f1:0i' , {'names' : ['f0' ,'f1' ],
7079
+ 'formats' : ['u1' ,'u1' ],
7080
+
903B
9;offsets' : [0 ,4 ],
7081
+ 'itemsize' : 8 })
7082
+ self ._check ('=B:f0:0iB:f1:0i' , [('f0' , 'u1' ), ('f1' , 'u1' )])
7083
+
7084
+ # PEP3118 cannot support overlapping/out-of-order fields
7085
+ # (update these tests if it is improved to allow this)
7086
+ a = np .empty (3 , dtype = {'names' : ['a' , 'b' ],
7087
+ 'formats' : ['i4' , 'i2' ],
7088
+ 'offsets' : [0 , 2 ]})
7089
+ assert_raises (ValueError , memoryview , a )
7090
+ a = np .empty (3 , dtype = 'i4,i4' )[['f1' , 'f0' ]]
7091
+ assert_raises (ValueError , memoryview , a )
7092
+
7059
7093
def test_native_padding_3 (self ):
7060
7094
dt = np .dtype (
7061
7095
[('a' , 'b' ), ('b' , 'i' ),
0 commit comments